【每日一题NO.57】for...in和Object.keys()的区别是什么?
目录:
前言
相同点:
二者的用法:
不同点总结:
用法不同
迭代的范围不同
前言
之前一篇文章里总结过Reflect.ownKeys()
与Object.keys()
的区别:
在文章最后也扩展总结了for...in与这两者的区别。
并且还列了一个清晰明了的表格:
今天我们再来回顾下这块知识,最后也会在下一篇再扩展一下for
、for...in
、for...of
的相关知识。
相同点:
二者都可以用来迭代对象,但是语法不一样、用法也不一样,就连迭代对象的结果也不一样。
二者的用法:
首先我们先来回忆下二者的用法:先定义一个对象用来使用,对象除了自己的实例属性,还有原型上的firstName属性。
const obj = { name: '小石头', age: 18 }
obj.__proto__.firstName = '郭'
可以看到对象的属性及原型链关系如下图:
for...in
for...in
是 JavaScript 中最常见的迭代语句,我们常常使用他迭代对象的属性,可以看到不光循环取出了对象上的属性,就连原型上firstName属性也被取出来了。
for ( let o in obj) {
console.log(o) // name、age、firstName
console.log(obj[o]) // '小石头'、18、郭
}
for...in
循环会枚举对象原型链上的可枚举属性
所以有时候你会看到这么使用,用Object.hasOwnProperty()
方法将原型上的数据过滤掉。
for (const key in obj) {
if (Object.hasOwnProperty.call(object, key)) {
const value = obj[key];
console.log(`当前键名是:${key},对应的值为${value}`);
}
}
这样就不会拿到原型上的属性了,循环打印结果如下:
Object.keys()
使用Object.keys()
将目标对象作为参数传进去后,得到一个对象所有可枚举属性名组成的数组。但是没有拿到对象原型链上的属性。
const keyArray = Object.keys(obj); // ['name', 'age']
tips:数组中属性名的顺序跟使用 for…in 遍历返回的顺序是一样的。
不同点总结:
用法不同
for…in
是遍历对象取出可枚举属性的值。而Object.keys()
是得到对象所有可枚举属性组成的数组。
如果你想获取一个对象的所有属性,,甚至包括不可枚举的,请查看Object.getOwnPropertyNames[1]
迭代的范围不同
for…in
可以得到对象原型链上的可枚举属性,Object.keys()
不行。
参考资料
Object.getOwnPropertyNames: 可以看MDN相关文章https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames
所有《每日一题》的 知识大纲索引脑图 整理在此:https://www.yuque.com/dfe_evernote/interview/everyday