在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 });