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啊。。
谢谢各位大神~~
###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.prototype
和 Array.prototype
。
由于继承和原型链,对象 iterable
继承属性 objCustom
和 arrCustom
,所以 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
。
for...in可以便利原型链