Javascript for … in循环使用Object.prototype和Array.prototype属性

Javascript for … in loop with Object.prototype and Array.prototype properties

本问题已经有最佳答案,请猛点这里访问。

我正在阅读MDN文档以更好地理解JavaScript。这是从那里摘录的

1
2
3
4
5
6
7
8
9
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2,"foo","arrCustom","objCustom"
}

在最坏的情况下,我以为它会打印0, 1, 2,"foo","arrCustom",但它也会打印objCustom

更新:1)如何可视化从iterableArray的原型链,一直到Object。就像有任何iterable.getParent方法或iterable.myparent属性指向父对象一样。2)为什么不打印数组函数,如toStringsort,它们也在Array.prototype上。3)当有人在Array.prototype属性中添加某些内容时,我是否需要始终使用hasOwnProperty


这是因为for in循环的目的是迭代所有可枚举的属性,包括拥有的和继承的。您可以使用Object.keys()只获取拥有的属性。

1
2
3
4
5
6
7
8
9
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

Object.keys(iterable).forEach(function(key) {
  console.log(key); // logs 0, 1, 2,"foo"
});

然而,在Array上放置非数字属性是非常不寻常的。通常有更好的方法来完成你需要做的事情。

在数组上使用for in循环也是不常见的。还有其他更好的迭代数组的方法,只要将数组限制在其数值索引内。

1)"How can i visualize the prototype chain from iterable to Array all the way upto Object. Like is there any iterable.getParent method or iterable.myparent property which points to parent on it."

可以使用Object.getPrototypeOf()获取对象继承的下一个对象。循环进行,直到到达null为止。

1
2
3
4
var proto = Object.getPrototypeOf(myObj);
do {
  console.log(proto);
} while((proto = Object.getPrototypeOf(proto)));

2)"why it does not print array functions such as toString, sort they are also on Array.prototype."

toString()和其他内置方法是不可枚举的。如上所述,for in只达到可枚举属性。

3)"Do i need to use hasOwnProperty always when someone add something to Array.prototype property."

不要在数组上使用for in循环,这样做会更好。但是,是的,如果使用for in,就需要.hasOwnProperty()样板代码来防止这种情况发生。

您还应该知道,在使用for in时,不能保证按顺序到达数组索引。而且它通常比其他的数组迭代方法慢得多。使用.hasOwnProperty()检查时速度特别慢。


因为for-in迭代对象的所有属性,包括从原型继承的属性。要跳过继承的属性,请使用hasOwnProperty()

1
2
3
4
5
6
7
8
9
10
11
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i);
  }
}


for..in循环遍历一个对象拥有的所有属性,这意味着它拥有自己的属性和继承的属性。这就是为什么for..inhasOwnProperty一起出现在美国的原因,就像这样。

1
2
3
4
5
6
7
8
9
10
11
12
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  if (iterable.hasOwnProperty(i))
    console.log('own', i); // logs 0, 1, 2,"foo"
  else
    console.log('not', i); // logs"arrCustom","objCustom" (inherited)
}