犹如 in
运算符一样,运用 for in
轮回遍历对象属性时,也将往上遍历全部原型链。
// Poisoning Object.prototype
Object.prototype.bar = 1;
var foo = {moo: 2};
for(var i in foo) {
console.log(i); // prints both bar and moo
}
这里我们要注意两点,一是 for in
轮回会疏忽 enumerable
设置为 false
的属性。比方一个数组的 length
属性。第二是,因为 for in
会遍历全部原型链,所以当原型链太长时,会对机能形成影响。
enumerable
是个很生疏的辞汇,实际上,你很难在javascript
中发明它的影子,而它实际上也是作者从ruby
中自创而来的。建立enumerable
的目标不是为了自力运用,而是采纳“混用”的体式格局,而Prototype
中许多要领都混用了enumerable
,所以它能够说是prototype
的奠基石。这里不做细致引见,细致内容能够参考 – Enumerable。
因为我们没法转变 for in
轮回自身的行动,所以我们只能采用其他要领来过滤掉那些不愿望涌如今轮回内的属性,经由过程 《细说 Javascript 对象篇(三) : hasOwnProperty》 我们晓得 hasOwnProperty
要领是能够做到这一点的。
运用 hasOwnProperty 过滤
依然运用上个例子:
// Poisoning Object.prototype
Object.prototype.bar = 1;
var foo = {moo: 2};
for(var i in foo) {
if (foo.hasOwnProperty(i)) {
console.log(i);
}
}
这是唯一准确的写法,因为我们实用了 hasOwnProperty
要领,所以此次只输出 moo
。假如不实用 hasOwnProperty
要领,那末当 Object.prototype
扩大时,就会涌现毛病。
如今许多框架都邑挑选从 Object.prototype
扩大要领,所以我们运用这些框架时,假如运用没有用 hasOwnProperty
过滤的 for in
轮回时就会遇到问题。
总结
发起养成 hasOwnProperty
过滤属性的好习惯,不要对运转环境做任何假定,也不管原生的原型对象是不是被扩大。
参考
http://bonsaiden.github.io/JavaScript-Garden/#object.forinloop