和 in
操作符一样,for in
循环同样在查找对象属性时遍历原型链上的所有属性。
注意: for in
循环不会遍历那些 enumerable
设置为false
的属性;比如数组的length
属性。
// 修改 Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { console.log(i); // 输出两个属性:bar 和 moo }
由于不可能改变 for in
自身的行为,因此有必要过滤出那些不希望出现在循环体中的属性, 这可以通过 Object.prototype
原型上的 hasOwnProperty
函数来完成。
注意: 由于 for in
总是要遍历整个原型链,因此如果一个对象的继承层次太深的话会影响性能。
使用 hasOwnProperty
过滤
// foo 变量是上例中的 for(var i in foo) { if (foo.hasOwnProperty(i)) { console.log(i); } }
这个版本的代码是唯一正确的写法。由于我们使用了 hasOwnProperty
,所以这次只输出 moo
。 如果不使用 hasOwnProperty
,则这段代码在原生对象原型(比如 Object.prototype
)被扩展时可能会出错。
一个广泛使用的类库 Prototype 就扩展了原生的 JavaScript 对象。 因此,当这个类库被包含在页面中时,不使用 hasOwnProperty
过滤的 for in
循环难免会出问题。
总结
推荐总是使用 hasOwnProperty
。不要对代码运行的环境做任何假设,不要假设原生对象是否已经被扩展了。
来源:https://www.cnblogs.com/luckyxb/p/6398503.html