for...in循環是 遍歷對象的每一個可枚舉屬性,包括原型鏈上面的可枚舉屬性,而Object.keys()只是遍歷自身的可枚舉屬性,不可以遍歷原型鏈上的可枚舉屬性. 這是for...in和Object.keys()的主要區別,而Object.getOwnPropertyNames()則是遍歷自身所有屬性(不論是否是可枚舉的),不包括原型鏈上面的.
舉個例子:
function People(){
this.name = 'Tom';
this.age = 24;
this.c = function(){
console.log('1');
}
}
People.prototype.look = function(){
console.log('look at this');
}
var b = new People();
//使用Object.defineProperty方法為b添加一個'sex'的不可枚舉屬性
Object.defineProperty(b,'sex',{
value:'女',
enumerable:false
});
for(var i in b){
console.log(i);
}
我們可以遍歷到對象b的所有可枚舉屬性,其中包括從原型繼承來的look.
接着我們使用Object.keys()來遍歷,代碼如下:
function People(){
this.name = 'Tom';
this.age = 24;
this.c = function(){
console.log('1');
}
}
People.prototype.look = function(){
console.log('look at this');
}
var b = new People();
//使用Object.defineProperty方法為b添加一個'sex'的不可枚舉屬性
Object.defineProperty(b,'sex',{
value:'女',
enumerable:false
});
console.log(Object.keys(b));//結果["name","age","c"]
從打印的結果我們看到, Object.keys()遍歷的是自身可枚舉屬性,他不包括原型鏈上的look.
下面我們使用Object.getOwnPropertyNames()方法試試,具體代碼如下:
function People(){
this.name = 'Tom';
this.age = 24;
this.c = function(){
console.log('1');
}
}
People.prototype.look = function(){
console.log('look at this');
}
var b = new People();
//使用Object.defineProperty方法為b添加一個'sex'的不可枚舉屬性
Object.defineProperty(b,'sex',{
value:'女',
enumerable:false
});
console.log(Object.getOwnPropertyNames(b));//結果["name", "age", "c", "sex"]
可以看到,Object.getOwnPropertyNames()遍歷的是自身的可枚舉和不可枚舉屬性, 不含原型鏈上的.
具體可以查看Object.keys()方法, for...in循環, Object.getOwnPropertyNames()方法,以及Object.defineProperty()方法.