JS的可枚举性
在学习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内的为实例对象自身属性~~