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 相关文章推荐
心扬JS分页函数代码
Sep 10 Javascript
javascript使用window.open提示“已经计划系统关机”的原因
Aug 15 Javascript
jQuery选择器源码解读(五):tokenize的解析过程
Mar 31 Javascript
jQuery的几个我们必须了解的特点
May 03 Javascript
jquery-tips悬浮提示插件分享
Jul 31 Javascript
判断是否存在子节点的实现代码
May 18 Javascript
jquery判断类型是不是number类型的实例代码
Oct 07 Javascript
JS实现的数字格式化功能示例
Feb 10 Javascript
JavaScript算法教程之sku(库存量单位)详解
Jun 29 Javascript
QRCode.js二维码生成并能长按识别
Oct 16 Javascript
微信小程序实现列表页的点赞和取消点赞功能
Nov 02 Javascript
Element Carousel 走马灯的具体实现
Jul 26 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 Cookie的使用教程详解
2013/06/03 PHP
destoon二次开发常用数据库操作
2014/06/21 PHP
php文件缓存类用法实例分析
2015/04/22 PHP
PHP设计模式之原型模式定义与用法详解
2018/04/03 PHP
彻底搞懂JS无缝滚动代码
2007/01/03 Javascript
禁止js文件缓存的代码
2010/04/09 Javascript
二叉树的非递归后序遍历算法实例详解
2014/02/07 Javascript
JavaScript日期时间格式化函数分享
2014/05/05 Javascript
JavaScript的jQuery库中function的存在和参数问题
2015/08/13 Javascript
jquery实现仿新浪微博带动画效果弹出层代码(可关闭、可拖动)
2015/10/12 Javascript
jQuery实用技巧必备(下)
2015/11/03 Javascript
gameboy网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点
2016/02/21 Javascript
通过隐藏iframe实现无刷新上传文件操作
2016/03/16 Javascript
探究JavaScript中的五种事件处理程序方式
2016/12/07 Javascript
jQuery对table表格进行增删改查
2020/12/22 Javascript
ExtJs异步无法向外传值和赋值的完美解决办法
2017/06/14 Javascript
jQuery实现可编辑表格并生成json结果(实例代码)
2017/07/19 jQuery
javascript input输入框模糊提示功能的实现
2017/09/25 Javascript
基于jQuery Ajax实现下拉框无刷新联动
2017/12/06 jQuery
Javascript Dom元素获取和添加详解
2019/09/24 Javascript
环形加载进度条封装(Vue插件版和原生js版)
2019/12/04 Javascript
详解Python中的序列化与反序列化的使用
2015/06/30 Python
Python的Django框架中从url中捕捉文本的方法
2015/07/20 Python
python实现录屏功能(亲测好用)
2020/03/02 Python
HTML5语音识别标签写法附图
2013/11/18 HTML / CSS
澳大利亚在线百货商店:Real Smart
2017/08/13 全球购物
TobyDeals美国:在电子产品上获得最好的优惠和折扣
2019/08/11 全球购物
什么时候需要进行强制类型转换
2016/09/03 面试题
机电专业大学生求职信
2013/10/04 职场文书
工商企业管理实习自我鉴定
2013/12/04 职场文书
银行营业厅大堂经理岗位职责
2014/01/06 职场文书
旅游项目开发策划书
2014/01/18 职场文书
教师师德师风自我剖析材料
2014/09/29 职场文书
预防艾滋病宣传活动总结
2015/05/09 职场文书
Vue的列表之渲染,排序,过滤详解
2022/02/24 Vue.js
PyTorch中permute的使用方法
2022/04/26 Python