JS对象的可枚举属性和不可枚举属性
在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable
值决定的。
Object.defineProperty(ykx, "sex", { value: "male", //是否为枚举属性 enumerable: false });
可枚举属性是指那些内部enumerable 标志设置为 true 的属性。对于通过直接的赋值和属性初始化的属性,该标识值默认为即为 true。但是对于通过 Object.defineProperty 等定义的属性,该标识值默认为 false。
其中js中基本包装类型的原型对象的属性是不可枚举的,如Object, Array, Number等。
可枚举的属性可以通过for...in循环进行遍历(除非该属性名是一个Symbol),或者通过Object.keys()方法可以返回一个可枚举属性的数组(Object.keys()不能返回不可枚举的属性)。
如果用Object.getOwnPropertyNames方法的话可以遍历到它所有的属性,包括可枚举和不可枚举的属性。
function Person() { this.name = "Ykx"; }; let ykx = new Person(); Object.defineProperty(ykx, "sex", { value: "male", //是否为枚举属性 enumerable: false }); console.log(Object.getOwnPropertyNames(ykx)); // ["name", "sex"]
上述三种获取属性的方法都有哪些区别?
for...in
遍历对象的每一个可枚举属性,包括原型链上面的可枚举属性:
function Person() { this.name = "Ykx"; }; Person.prototype.School = 'Tust'; Object.defineProperty(ykx, "sex", { value: "male", //是否为枚举属性 enumerable: false }); let ykx = new Person(); for(var p in ykx){ console.log(p); //name,School }
Object.keys()
Object.keys方法只能遍历自己的对象上的可枚举的属性,不能遍历自己原型上可枚举的属性:
function Person() { this.name = "Ykx"; }; Person.prototype.School = 'Tust'; Object.defineProperty(ykx, "sex", { value: "male", //是否为枚举属性 enumerable: false }); let ykx = new Person(); Object.keys(ykx).forEach(function(key) { console.log(key) //name });
Object.getOwnPropertyNames()
Object.getOwnPropertyNames()遍历自身对象的所有属性,包括可枚举不可枚举,但是原型上的属性是无法遍历的:
function Person() { this.name = "Ykx"; }; Person.prototype.School = 'Tust'; Object.defineProperty(ykx, "sex", { value: "male", //是否为枚举属性 enumerable: false }); let ykx = new Person(); Object.getOwnPropertyNames(ykx).forEach(function(key) { console.log(key);//name,sex });