JS:for...in...,Objects.keys()和Object.getOwnPropertyNames的区别

原创
2017/10/17 17:25
阅读数 310

简介

javascript是一门面向对象的语言,在javascript中,一切都是对象。对象的属性包括了数据属性和访问器属性,根据实际情况,我们又可以把对象的属性分为原型属性和实例属性。下面我们以三个例子来分别看看 for...in...,Object.keys和Object.getOwnPropertyNames 在遍历对象属性时的不同

for...in...

var testData = ["one","two","three"]
var testMap = {"index1":1,"index2":2,"index3":3};
function Person(name,sex){
  this.name = "Thomas";
  this.sex = "male";
}
Person.prototype.getName = function(){ return this.name} //拓展prototype属性

for(var i in testData){
  console.log(i);  //输出0,1,2
   
}
for(var i in testMap){
  console.log(i);// "index1","index2","index3"  返回所有的
}
var personOne = new Person();
for(var prop in personOne){
  console.log(prop) //name,sex,getName 返回可枚举的属性,包括原型链上的
}

这里我们看到,利用for...in..遍历test时,输出的是0,1,2。为什么是这样子呢?其实我们可以把数组看成是

{
  0:"one",
  1:"two",
  2:"three"
 }

这就是我们为什么可以通过test[0],test[1],test[2]来访问到这些数据的重要原因。

Object.keys()

var testData = ["one","two","three"]
var testMap = {"index1":1,"index2":2,"index3":3};
function Person(name,sex){
  this.name = "Thomas";
  this.sex = "male";
}
Person.prototype.getName = function(){ return this.name} //拓展prototype属性

console.log(Object.keys(testData)); //["0", "1", "2"]
console.log(Object.keys(testMap)); // "index1","index2","index3"  返回所有的

var personOne = new Person();
console.log(Object.keys(personOne));//["name", "sex"],无法获取原型链上的属性

Object.getOwnPropertyNames()

var testData = ["one","two","three"]
var testMap = {"index1":1,"index2":2,"index3":3};
function Person(name,sex){
  this.name = "Thomas";
  this.sex = "male";
}
Person.prototype.getName = function(){ return this.name} //拓展prototype属性

console.log(Object.getOwnPropertyNames(testData)); //["0", "1", "2","length"],包括可枚举和不可枚举的属性
console.log(Object.getOwnPropertyNames(testMap)); // "index1","index2","index3"  
var personOne = new Person();
console.log(Object.getOwnPropertyNames(personOne));//["name", "sex"],无法获取原型链上的属性

可以看到

方法 作用
for...in.. 以任意顺序遍历一个对象的可枚举属性,包括原型链上的
Object.keys() 返回对象的可枚举属性组成的数组
Object.getOwnPropertyNames 返回对象可枚举和不可枚举的属性,不包含Symbol值作为名称的值。

备注:对象属性的可枚举或者不可枚举可以通过Object.defineProperty来重新定义,例如,在前面的程序中,我们重新修改一下代码:


function Person(name,sex){
  this.name = "Thomas";
  this.sex = "male";
}
Person.prototype.getName = function(){ return this.name} //拓展prototype属性
var personOne = new Person();
Object.defineProperty(personOne,"name",{
  enumerable: false,
  configurable: false,
  writable: false,
})
console.log(Object.keys(personOne));//结果是:["sex"],原本是 ["name","sex"].这是name属性变得不可枚举

 

参考链接:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...in

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部