JS 5种遍历对象的方式
几天前一个小伙伴问我 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 遍历对象的资料请关注其它相关文章!