JS 5种遍历对象的方式


Posted in Javascript onJune 16, 2020

几天前一个小伙伴问我 Object.getOwnPropertyNames() 是干什么用的

平时还真没有使用到这个方法,一时不知如何回答

从方法名称来分析,应该是返回的是对象自身属性名组成的数组

那和 Object.keys() 方法不就一样了吗

感觉事情并不这么简单,于是我仔细看了一下这几种遍历对象的方法的区别

for in

for in 循环是最基础的遍历对象的方式,它还会得到对象原型链上的属性

// 创建一个对象并指定其原型,bar 为原型上的属性
const obj = Object.create({
 bar: 'bar'
})

// foo 为对象自身的属性
obj.foo = 'foo'

for (let key in obj) {
 console.log(obj[key]) // foo, bar
}

可以看到对象原型上的属性也被循环出来了

在这种情况下可以使用对象的 hasOwnProperty() 方法过滤掉原型链上的属性

for (let key in obj) {
 if (obj.hasOwnProperty(key)) {
  console.log(obj[key]) // foo
 }
}

这时候原型上的 bar 属性就被过滤掉了

Object.keys

Object.keys() 是 ES5 新增的一个对象方法,该方法返回对象自身属性名组成的数组,它会自动过滤掉原型链上的属性,然后可以通过数组的 forEach() 方法来遍历

Object.keys(obj).forEach((key) => {
 console.log(obj[key]) // foo
})

另外还有 Object.values() 方法和 Object.entries() 方法,这两方法的作用范围和 Object.keys() 方法类似,因此不再说明

for in 循环和 Object.keys() 方法都不会返回对象的不可枚举属性

如果需要遍历不可枚举的属性,就要用到前面提到的 Object.getOwnPropertyNames() 方法了

Object.getOwnPropertyNames

Object.getOwnPropertyNames() 也是 ES5 新增的一个对象方法,该方法返回对象自身属性名组成的数组,包括不可枚举的属性,也可以通过数组的 forEach 方法来遍历

// 创建一个对象并指定其原型,bar 为原型上的属性
// baz 为对象自身的属性并且不可枚举
const obj = Object.create({
 bar: 'bar'
}, {
 baz: {
  value: 'baz',
  enumerable: false
 }
})

obj.foo = 'foo'

// 不包括不可枚举的 baz 属性
Object.keys(obj).forEach((key) => {
 console.log(obj[key]) // foo
})

// 包括不可枚举的 baz 属性
Object.getOwnPropertyNames(obj).forEach((key) => {
 console.log(obj[key]) // baz, foo
})

ES2015 新增了 Symbol 数据类型,该类型可以作为对象的键,针对该类型 ES2015 同样新增Object.getOwnPropertySymbols() 方法

Object.getOwnPropertySymbols

Object.getOwnPropertySymbols() 方法返回对象自身的 Symbol 属性组成的数组,不包括字符串属性

Object.getOwnPropertySymbols(obj).forEach((key) => {
 console.log(obj[key])
})

什么都没有,因为该对象还没有 Symbol 属性

// 给对象添加一个不可枚举的 Symbol 属性
Object.defineProperties(obj, {
 [Symbol('baz')]: {
  value: 'Symbol baz',
  enumerable: false
 }
})

// 给对象添加一个可枚举的 Symbol 属性
obj[Symbol('foo')] = 'Symbol foo'

Object.getOwnPropertySymbols(obj).forEach((key) => {
 console.log(obj[key]) // Symbol baz, Symbol foo
})

Reflect.ownKeys

Reflect.ownKeys() 方法是 ES2015 新增的静态方法,该方法返回对象自身所有属性名组成的数组,包括不可枚举的属性和 Symbol 属性

Reflect.ownKeys(obj).forEach((key) => {
 console.log(obj[key]) // baz, foo, Symbol baz, Symbol foo
})

对比

方式 基本属性 原型链 不可枚举 Symbol
for in
Object.keys()
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Reflect.ownKeys()

结论

这其中只有 for in 循环会得到对象原型链上的属性,其它方法都只适用于对象自身的属性

ES 语言后续添加的新特性不会对以前的代码产生副作用,比如在 ES2015 之前就存在的 for in 循环,Object.keys() 和 Object.getOwnPropertyNames() 是肯定不会返回 Symbol 属性的

以上就是JS 5种遍历对象的方式的详细内容,更多关于JS 遍历对象的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
JavaScript的9个陷阱及评点分析
May 16 Javascript
js form 验证函数 当前比较流行的错误提示
Jun 23 Javascript
对之前写的jquery分页做下升级
Jun 19 Javascript
javascript在IE下trim函数无法使用的解决方法
Sep 12 Javascript
深入理解JavaScript中为什么string可以拥有方法
May 24 Javascript
JavaScript实现自定义媒体播放器方法介绍
Jan 03 Javascript
Javascript实现数组中的元素上下移动
Apr 28 Javascript
react开发中如何使用require.ensure加载es6风格的组件
May 09 Javascript
js微信应用场景之微信音乐相册案例分享
Aug 11 Javascript
vue实现按需加载组件及异步组件功能
May 27 Javascript
浅谈bootstrap layer.open中end的使用方法
Sep 12 Javascript
微信小程序中的video视频实现 自定义播放按钮、封面图、视频封面上文案
Jan 02 Javascript
js实现小球在页面规定的区域运动
Jun 16 #Javascript
Vue结合路由配置递归实现菜单栏功能
Jun 16 #Javascript
vue 实现在同一界面实现组件的动态添加和删除功能
Jun 16 #Javascript
详解JS预解析原理
Jun 16 #Javascript
深入了解JS之作用域和闭包
Jun 16 #Javascript
JS数组及对象遍历方法代码汇总
Jun 16 #Javascript
浅谈Vue 函数式组件的使用技巧
Jun 16 #Javascript
You might like
解析PHP中常见的mongodb查询操作
2013/06/20 PHP
CI框架AR数据库操作常用函数总结
2016/11/21 PHP
php+mysql+jquery实现简易的检索自动补全提示功能
2017/04/15 PHP
php实现的rc4加密解密类定义与用法示例
2018/08/16 PHP
Laravel5.5 视图 - 创建视图和数据传递示例
2019/10/21 PHP
ASP Json Parser修正版
2009/12/06 Javascript
js函数中onmousedown和onclick的区别和联系探讨
2013/05/19 Javascript
js 日期比较相关天数代码
2014/04/02 Javascript
jQuery中map()方法用法实例
2015/01/06 Javascript
js立即执行函数: (function ( ){})( ) 与 (function ( ){}( )) 有什么区别?
2015/11/18 Javascript
angularjs表格分页功能详解
2016/01/21 Javascript
浅析jquery数组删除指定元素的方法:grep()
2016/05/19 Javascript
深入理解Javascript中的自执行匿名函数
2016/06/03 Javascript
如何解决IONIC页面底部被遮住无法向上滚动问题
2016/09/06 Javascript
etmvc+jQuery EasyUI+combobox多值操作实现角色授权实例
2016/11/09 Javascript
AngularJS封装$http.post()实例详解
2017/05/06 Javascript
JavaScript函数apply()和call()用法与异同分析
2018/08/10 Javascript
详解vuex的简单todolist例子
2019/07/14 Javascript
js模拟F11页面全屏显示
2019/09/17 Javascript
vue实现放大镜效果
2020/09/17 Javascript
vue+elementui通用弹窗的实现(新增+编辑)
2021/01/07 Vue.js
Python实现嵌套列表去重方法示例
2017/12/28 Python
Python反射的用法实例分析
2018/02/11 Python
PyQt5每天必学之进度条效果
2018/04/19 Python
如何在Django中设置定时任务的方法示例
2019/01/18 Python
Django页面数据的缓存与使用的具体方法
2019/04/23 Python
django创建最简单HTML页面跳转方法
2019/08/16 Python
深入浅析python的第三方库pandas
2020/02/13 Python
基于Html5实现的react拖拽排序组件示例
2018/08/13 HTML / CSS
名词解释型面试题(主要是网络)
2013/12/27 面试题
公司财务自我评价分享
2013/12/17 职场文书
省级三好学生主要事迹材料
2015/11/03 职场文书
音乐研修感悟
2015/11/18 职场文书
如何撰写出一份完美的商业计划书?
2019/07/12 职场文书
教你使用TensorFlow2识别验证码
2021/06/11 Python
MySQL图形化管理工具Navicat安装步骤
2021/12/04 MySQL