• ES6 之 对象属性的可枚举性和遍历


    1.Object.getOwnPropertyDescriptor()

    解释:获取对对象属性的描述对象。

    let obj = { foo: 123 };
    console.log(Object.getOwnPropertyDescriptor(obj, 'foo'))

    显示结果:

    {
        configurable: true
        enumerable: true
        value: 123
        writable: true
        __proto__: Object
    }

    enumerable属性,称为可枚举性,如果为 false 时,就表示某些操作会忽略当前属性。

    目前,有四个操作会忽略enumerable为 false 的属性。

    • for...in循环:只遍历对象自身的和继承的可枚举的属性。
    • Object.keys():返回对象自身的所有可枚举的属性的键名。使用这个遍历对象!
    • JSON.stringify():只串行化对象自身的可枚举的属性。
    • Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性
    Object.getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable // false 
     
    Object.getOwnPropertyDescriptor([], 'length').enumerable // false
    
    // toString和length属性的enumerable都是false,因此for...in不会遍历到这两个继承自原型的属性。

    2. Object.getOwnPropertyDescriptors()

    Object.getOwnPropertyDescriptors 方法,返回指定对象所有自身属性(非继承属性)的描述对象。

    const obj = {   foo: 123,   get bar() { return 'abc' } }; 
     
    Object.getOwnPropertyDescriptors(obj) 
    
    // { foo: 
    //    { value: 123, 
    //      writable: true, 
    //      enumerable: true, 
    //      configurable: true }, 
    //   bar: 
    //    { get: [Function: bar],
    //      set: undefined, 
    //      enumerable: true, 
    //      configurable: true } }

    上面代码中,Object.getOwnPropertyDescriptors(obj)方法返回一个对象,所有原对象的属性名都是该对象的属性名,对应的属性值就是该属性的描述对象。

    3. Object.setPrototypeOf()

    用于设置一个对象的原型对象。

    // 格式 
    Object.setPrototypeOf(object, prototype) 
     
    // 用法 
    const o = Object.setPrototypeOf({}, null); 
    
    // 该方法等同于下面的函数。
    function (obj, proto) {   
        obj.__proto__ = proto;   
        return obj; 
    }

    例子:

    let proto = {}; 
    let obj = { x: 10 }; 
    Object.setPrototypeOf(obj, proto); 
     
    proto.y = 20;
    proto.z = 40; 
     
    obj.x // 10 
    obj.y // 20 
    obj.z // 40

    注意:

    1. 如果第一个参数不是对象,会自动转为对象。但是由于返回的还是第一个参数,所以这个操作不会产生任何效果。

    2. 由于undefined和null无法转为对象,所以如果第一个参数是undefined或null,就会报错。

    4. Object.getPrototypeOf()

    该方法与Object.setPrototypeOf方法配套,用于读取一个对象的原型对象。

    Object.getPrototypeOf(obj); 
    1. 如果参数不是对象,会被自动转为对象。

    2. 如果参数是undefined或null,它们无法转为对象,所以会报错。

    5. super关键字

    我们知道,this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象

    const proto = {   foo: 'hello' }; 
     
    const obj = {   
        find() {     
            return super.foo;   
        } 
    }; 
    
    Object.setPrototypeOf(obj, proto);
    obj.find() // "hello" 
    // 上面代码中,对象obj的find方法之中,通过super.foo引用了原型对象proto的foo属性。

    注意,super关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错。

    JavaScript 引擎内部,super.foo等同于Object.getPrototypeOf(this).foo(属性)或Object.getPrototypeOf(this).foo.call(this)(方法)。

    例题:

    const proto = {   
        x: 'hello',   
        foo() {     
            console.log(this.x);   
        }, 
    }; 
     
    const obj = {   
        x: 'world',   
        foo() {    
            super.foo();   
        } 
    } 
     
    Object.setPrototypeOf(obj, proto); 
     
    obj.foo() // "world" 
    
    // 上面代码中,super.foo指向原型对象proto的foo方法,但是绑定的this却还是当前对象obj,因此输出的就是world。

    6. Object.keys(),Object.values(),Object.entries()

    Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。

    var obj = { foo: 'bar', baz: 42 }; 
    Object.keys(obj) // ["foo", "baz"] 

    ES2017 引入了跟Object.keys配套的Object.valuesObject.entries,作为遍历一个对象的补充手段,供for...of循环使用

    Object.values方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。

    const obj = { 100: 'a', 2: 'b', 7: 'c' }; 
    Object.values(obj) // ["b", "c", "a"] 

    上面代码中,属性名为数值的属性,是按照数值大小,从小到大遍历的,因此返回的顺序是b、c、a。

    Object.values只返回对象自身的可遍历属性。

     

    Object.entries方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。

    const obj = { foo: 'bar', baz: 42 }; 
    Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]

    除了返回值不一样,该方法的行为与Object.values基本一致。

     遍历语法的比较

    对于数组来说:

    for循环:最原始的写法;

    forEach:无法中途跳出forEach循环,break命令或return命令都不能奏效;

    for...in...:遍历可以获得数组的键名,有以下缺点:

      数组的键是number,而遍历出来的键是字符串;

      for...in循环不仅遍历数字键名,还会遍历手动添加其他键,甚至包括原型链上的键

      在某些情况下,for...in循环会以任意顺序遍历键名

      总之,for...in循环主要是为了遍历对象而设计的,不适用于遍历数组

     for...of:遍历数组 

      有着同for..in样简单语法,但是没有for...in那些缺点,

      不同于 forEach 方法,它可以与 break 、 continue 和 return 配合使用。

      提供了遍历所有数据结构的统一操作接口。

     

  • 相关阅读:
    兑奖
    杨辉三角
    偶数求和
    进制转化
    填词
    等值数目
    Spring框架的七个模块
    数据库中的第1、2、3范式 (昨天没睡好,因为那个蚊子~~)
    关于eclipse 不编译或者找不到*.class的问题
    servlet生命周期的理解
  • 原文地址:https://www.cnblogs.com/houfee/p/11271003.html
Copyright © 2020-2023  润新知