我正在阅读MDN docs以更好地理解javascript。这是摘录
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)如何将原型链从iterable
可视化到Array
一直到Object
。就像有任何iterable.getParent
方法或iterable.myparent
属性指向其上的父级一样
2)为什么它不打印toString
,sort
等数组函数,它们也在Array.prototype
上。
3)当有人向hasOwnProperty
财产添加内容时,我是否需要Array.prototype
使用。
答案 0 :(得分:5)
这是因为for in
循环意味着迭代所有可拥有和继承的可枚举属性。您可以使用Object.keys()
仅获取拥有的属性。
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)"我如何将原型链从可迭代到数组一直可视化到
Object
。就像有任何iterable.getParent方法或iterable.myparent属性一样,它指向父级。"
您可以使用Object.getPrototypeOf()
来获取对象继承的下一个对象。在循环中执行直到达到null
。
var proto = Object.getPrototypeOf(myObj);
do {
console.log(proto);
} while((proto = Object.getPrototypeOf(proto)));
2)"为什么它不打印
toString
等数组函数,排序它们也在Array.prototype
上。"
toString()
和其他内置方法不可枚举。如上所述,for in
只能访问可枚举的属性。
3)"当有人向
hasOwnProperty
财产添加内容时,我是否需要Array.prototype
使用{&#34>
不要在阵列上使用for in
循环,你会做得更好。但是,是的,如果您使用for in
,则需要.hasOwnProperty()
样板代码来防范。
您还应该知道,在使用for in
时,无法保证将按顺序访问数组索引。并且它通常比其他Array迭代方法慢得多。 .hasOwnProperty()
检查时速度特别慢。
答案 1 :(得分:4)
因为for-in
遍历对象的所有属性,包括从原型继承的属性。要跳过继承的属性,请使用hasOwnProperty()
。
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);
}
}

答案 2 :(得分:1)
for..in
循环遍历对象拥有的所有属性,这意味着拥有自己的属性并继承。这就是为什么for..in
伴随着hasOwnProperty
,就像这个
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)
}