大部分编辑器都有代码块功能, 某些编辑器(如VS code)提供的 for…in 代码块代码如下
for (const key in object) {
if (object.hasOwnProperty(key)) {
const element = object[key];
}
}
除了 for (in) {} 外, 还包含了一个 object.hasOwnProperty(key) 判断
当时年轻的我就很纳闷, 为什么要有这么一个判断, key 来自于 object, 所以必然属于 object, 这样的判断不是多此一举吗?
因此并没有意识到 object.hasOwnProperty(key) 判断的重要性
直到遇见了这样一个对象
var arr = {
a: "lv1",
__proto__: {
b: "lv2",
__proto__: {
c: "lv3",
__proto__: {
c: "lv4",
}
}
}
}
for(const key in arr) {
console.log(key, arr[key])
};
// a lv1
// b lv2
// c lv3
除了第一层 a lv1, 还输出了奇怪的东西 b lv2, c lv3
显然, 这并不是我所期望得到的结果!
所幸我的原型链基础还是有一点的, 知道那些奇怪的东西是来自于原型链 __proto__ 的深处, 再到网上一核实, 并清楚了问题的缘由
for…in 的遍历范围包括它的原型链
而且, 只要属性名不冲突, 原型链再深的属性都能揪出来
既然知道了问题的症结所在, 解决问题就轻而易举了
hasOwnProperty
hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)
简单来说就是用 hasOwnProperty 判断属性是对象自己的, 而非继承回来或别人的
原来 for…in 中的 if(object.hasOwnProperty(key)) {} 要排除的渣滓不是来自于外界, 而是对象自己的原型
毫无疑问, 加上 object.hasOwnProperty(key) 判断后, 结果就符合预期的效果了
var arr = {
a: "lv1",
__proto__: {
b: "lv2",
__proto__: {
c: "lv3",
__proto__: {
c: "lv4",
}
}
}
}
for(const key in arr) {
if(arr.hasOwnProperty(key)) {
console.log(key, arr[key])
}
};
// a lv1
//end