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 相关文章推荐
Jquery获得控件值的三种方法总结
Feb 13 Javascript
js的延迟执行问题分析
Jun 23 Javascript
jquery 插件实现瀑布流图片展示实例
Apr 03 Javascript
jQuery实现高亮显示网页关键词的方法
Aug 07 Javascript
利用jquery实现瀑布流3种案例
Sep 18 Javascript
详解Node.Js如何处理post数据
Sep 19 Javascript
原生JS实现的跳一跳小游戏完整实例
Jan 27 Javascript
详解为什么Vue中不要用index作为key(diff算法)
Apr 04 Javascript
关于vue3默认把所有onSomething当作v-on事件绑定的思考
May 15 Javascript
vue通过v-html指令渲染的富文本无法修改样式的解决方案
May 20 Javascript
vue 中 get / delete 传递数组参数方法
Mar 23 Vue.js
三种方式清除vue路由跳转router-link的历史记录
Apr 10 Vue.js
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 Static关键字实用方法
2010/06/04 PHP
php使用Cookie控制访问授权的方法
2015/01/21 PHP
thinkPHP5.0框架整体架构总览【应用,模块,MVC,驱动,行为,命名空间等】
2017/03/25 PHP
js Dialog 实践分享
2012/10/22 Javascript
原生Js页面滚动延迟加载图片实现原理及过程
2013/06/24 Javascript
Javascript实现带关闭按钮的网页漂浮广告代码
2014/01/12 Javascript
详解JS函数重载
2014/12/04 Javascript
jQuery控制cookie过期时间的方法
2015/04/07 Javascript
javaScript中slice函数用法实例分析
2015/06/08 Javascript
JQuery导航菜单选择特效
2016/04/11 Javascript
使用plupload自定义参数实现多文件上传
2016/07/19 Javascript
微信小程序 实现动态显示和隐藏某个控件
2017/04/27 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
2017/05/24 Javascript
vue中component组件的props使用详解
2017/09/04 Javascript
jQuery分组选择器简单用法示例
2019/04/04 jQuery
React如何实现浏览器打印部分内容详析
2019/05/19 Javascript
JavaScript展开操作符(Spread operator)详解
2019/07/20 Javascript
Servlet返回的数据js解析2种方法
2019/12/12 Javascript
[01:00:14]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs TNC 第三场
2018/04/10 DOTA
在Django的模型和公用函数中使用惰性翻译对象
2015/07/27 Python
Python实现字典依据value排序
2016/02/24 Python
Python高级特性切片(Slice)操作详解
2018/09/27 Python
python如何实现一个刷网页小程序
2018/11/27 Python
利用python实现短信和电话提醒功能的例子
2019/08/08 Python
Python:slice与indices的用法
2019/11/25 Python
python用TensorFlow做图像识别的实现
2020/04/21 Python
python os.rename实例用法详解
2020/12/06 Python
Marc Jacobs官方网站:美国奢侈品牌
2017/08/29 全球购物
CHARLES & KEITH澳大利亚官网:新加坡时尚品牌
2019/01/22 全球购物
RIP版本1跟版本2的区别
2013/12/30 面试题
程序员岗位职责
2013/11/11 职场文书
冬季作息时间调整通知
2015/04/24 职场文书
幼儿园科学课教学反思
2016/03/03 职场文书
Eclipse+Java+Swing+Mysql实现电影购票系统(详细代码)
2022/01/18 Java/Android
Python可变与不可变数据和深拷贝与浅拷贝
2022/04/06 Python
使用scrapy实现增量式爬取方式
2022/06/21 Python