美文网首页
对象的扩展

对象的扩展

作者: Jason_Shu | 来源:发表于2019-01-23 13:37 被阅读0次

    1. 对象属性的可枚举性和遍历

    let obj = { a: 1};
    
    Object.getOwnPropertyDescriptor(obj, 'a')
    // configurable: true
    // enumerable: true
    // value: 1
    // writable: true
    

    「enumerable」属性成为「可枚举性」,如果该属性为false,有一些操作会省略当前属性。

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

    • 「for...in」循环:只遍历对象「自身」和「继承」的可枚举属性。
    • 「Object.keys()」:返回对象「自身」的所有可枚举的属性的「键名」。
    • 「JSON.stringify()」:只串行化对象「自身」的可枚举属性。
    • 「Object.assign()」:忽略「enumerable」为false的属性,只拷贝对象「自身」的可枚举的属性。

    属性的遍历

    • 「for...in」遍历对象「自身」和「继承」的可枚举属性。(不包括Symbol属性)
    • 「Object.keys()」返回一个数组,包括对象「自身」的(不包括继承的)所有可枚举属性的键名。(不包括Symbol属性)
    • 「Object.getOwnPropertyNames(obj)」, 返回一个数组,包含对象「自身」的所有属性的键名。(不包括Symbol属性,但是包含不可枚举的属性)
    • 「Object.getOwnPropertySymbols(obj)」,返回一个数组,包含对象「自身」的所有Symbol属性的键名。
    • 「Reflect.ownKeys(obj)」,返回一个数组,包括对象「自身」的所有键名。(不管键名是否为Symbol值,不管是否可枚举)。

    2. 扩展字符串

    解构赋值是「浅拷贝」,即如果一个键的值是复合类型的值(数组,对象、函数),那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。

    let obj = { a: { b: 1 } };
    let { ...x } = obj;
    obj.a.b = 2;
    x.a.b // 2
    

    扩展运算符的解构赋值,不能复制继承自「原型对象」的属性。

    const o = Object.create({ x: 1, y: 2 });
    o.z = 3;
    
    let { x, ...newObj } = o;
    let { y, z } = newObj;
    x // 1
    y // undefined
    z // 3
    

    对象的解构赋值等同于使用「Object.assign()」方法。

    let aClone = { ...a };
    // 等同于
    let bClone = Object.assign({}, a);
    

    上面这个例子只是拷贝了对象实例的属性,如果想完全克隆一个对象,还要拷贝对象原型的属性。

    // 写法一
    const clone2 = Object.assign(
      Object.create(Object.getPrototypeOf(obj)),  // Object.getPrototypeOf(),返回原型对象
      obj
    );
    
    // 写法二
    const clone3 = Object.create(
      Object.getPrototypeOf(obj),
      Object.getOwnPropertyDescriptors(obj)
    )
    

    参考:http://es6.ruanyifeng.com/#docs/object

    相关文章

      网友评论

          本文标题:对象的扩展

          本文链接:https://www.haomeiwen.com/subject/xskjjqtx.html