简介
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属性变得不可枚举
参考链接: