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内的为实例对象自身属性~~
            
posted @ 2017-05-02 20:28  蒲公英tt  阅读(4321)  评论(2编辑  收藏  举报