在學習ES6的過程中,涉及到遍歷方法時,提到過可枚舉性,且多種遍歷方法都與可枚舉性相關。本章節,將總結這些遍歷方法的可枚舉性,並在必要的部分,給出對比實例。
一、設置屬性的可枚舉性
在上一文章“
Object的原型克隆”中,簡單介紹了Object.defineProperty()方法。通過該方法的屬性描述符 enumerable,就可以設置該屬性是否可以枚舉,當設置為false時,不可枚舉;否則,可枚舉。如示例:
Object.defineProperty(obj1, 'test', { configurable: false, enumerable: false, value: 'not enumerable' });
將obj1的test屬性,設置成不可枚舉類型。其中的obj1為原型繼承實例對象,相關源碼可查看上一章 “
Object的原型克隆”。
其屬性結構如下圖:

以上為chrome下控制台obj1的輸出截圖,可以看到屬性test顯示為帶灰度的色值,為不可枚舉屬性。
二、如何驗證可枚舉性
可通過 Object.getOwnPropertyDescriptor() 實現驗證,如實例:
Object.getOwnPropertyDescriptor(obj1, 'test').enumerable,為false則為不可枚舉。
tips:僅驗證自身屬性的可枚舉性,繼承屬性無法驗證哦~~
三、與可枚舉性相關的操作和方法
3.1、總覽
a、for…in:遍歷自身和繼承的可枚舉屬性;
b、Object.keys():返回對象自身的可枚舉屬性鍵名;
c、JSON.stringify():串行化對象自身的可枚舉屬性;
d、Object.assign():復制自身可枚舉的屬性;
e、Reflect.enumerate():返回所有for...in循環會遍歷的屬性;
f、所有Class的原型的方法都不可枚舉。
通過第一節中obj1的屬性結構截圖可分析其屬性的組成:
自身屬性:age、colors、name、test(不可枚舉);
原型(繼承)屬性:sayAge、sayName。
3.2、實驗數據驗證
a、for…in
符合預期,除test屬性不可枚舉外,其他屬性都可遍歷到;
b、Object.keys()
符合預期,僅遍歷到自身可枚舉屬性;
c、JSON.stringify()
符合預期,僅解析自身可枚舉屬性;
d、Object.assign()

符合預期,僅復制自身可枚舉屬性;
e、Reflect.enumerate() 在chrome中還未實現,暫無法驗證。
f、驗證Class的原型方法都不可枚舉
class Points { constructor(name, age) { this.name = name; this.age = age; } } Object.assign(Points.prototype, SubType.prototype); let point = new Points('puppy', 1);
point實例的屬性結構如下:

通過chrome的控制台,可以看出繼承的原型屬性中,sayAge與sayName均為可枚舉屬性,看似與預期不符合?
下面對Class進行擴展,進一步驗證:
class Points { constructor(name, age) { this.name = name; this.age = age; } sayName() { console.log(this.name) } sayColor() { console.log(this.color) } }
chrome控制台輸出:

其中的sayColor和sayName均不可枚舉,符合預期。因此得出結論:
通過Class定義的原型方法,不可枚舉,且如果這些方法覆蓋了原有的方法,這些方法也將不可枚舉。
tips:直接寫入Class里的屬性,為原型屬性,所有實例共有;寫在constructor內的為實例對象自身屬性~~