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()遍历的是自身的可枚举和不可枚举属性, 不含原型链上的.
具体可以查看方法, , 方法,以及方法.