小白请教~~~for…in 与 prototype的问题。 谢谢!

小鱼
  • 35
Object.prototype.abc = 'abcValue';
Array.prototype.def = 'defValue';

const obj = {key1: 'value1', key2: 'value2', key3: 'value3'};

for(let o in obj) {
    console.log(o);
}

const array = ['value1', 'value2', 'value3'];

for(let a in array) {
    console.log(a);
}

请问,第二个打印结果 `
console.log(a);`
为什么会把"abc"也打印出来呢? abc是Object.prototype啊。。

谢谢各位大神~~

回复
阅读 428
5 个回答
✓ 已被采纳

Array也属于Object

for...in 语句以任意顺序迭代对象的可枚举属性。

配合着demo来看吧

// 为对象和数组原型增加方法
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};

// 声明数组并赋值
let iterable = [3, 5, 7];
iterable.foo = 'hello';

// for...in 遍历输出属性名
for (let i in iterable) {
  console.log(i); // 0, 1, 2, "foo", "arrCustom", "objCustom"
}

// for...in 判断是否拥有属性并输出属性名
for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // 0, 1, 2, "foo"
  }
}
// arrCustom和objCustom不会被输出,因为它们是继承的,并非自身的属性

每个对象将继承 objCustom 属性,并且作为 Array 的每个对象将继承 arrCustom 属性,因为将这些属性添加到 Object.prototypeArray.prototype
由于继承和原型链,对象 iterable 继承属性 objCustomarrCustom,所以 for...in 会遍历出所有属性名,包括数组元素的下标和继承下来的属性。

之前有整理过for循环相关的,有兴趣你可以看看 JS 中的各种 for 循环

所有对象都继承自 Object

Array.prototype.__proto__ === Object.prototype; // true

你这俩都会打印abc,因为 for in 循环会遍历对象的原型链,可以使用Object.prototype.hasOwnProperty(props)这个方法来限定,

if(array.hasOwnProperty(o)){
    console.log(o)
 }

第二个也会打印,是因为原型链,无论是数组还是对象还是函数,他们在JS中都是对象,所谓的JS中万物皆对象,都继承了 Object.prototype 上面的属性,都会一直在原型链上查找,直到null

洪荒之力写bug
  • 1
新手上路,请多包涵

for...in可以便利原型链

你知道吗?

宣传栏