zoukankan      html  css  js  c++  java
  • 扩展运算符 ...

    解构赋值

        对象的解构赋值,用于从一个对象取值,相当于将目标对象自身的所有可遍历,但尚未被读取的属性,分配到指定的对象上边。所有的键和它们的值,都会拷贝到新对象上边。

    let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
     x // 1
     y // 2
     z // { a: 3, b: 4 }

    以上代码中,变量z是解构赋值所在的对象。它获取等号右边的所有尚未读取的键(a 和 b),将它们连同值一起拷贝过来。

    由于数组是特殊的对象,所以对象的扩展运算符也可以用于数组。

    let foo = { ...['a', 'b', 'c'] };
    foo
    // {0: "a", 1: "b", 2: "c"}

    注意:

         1、由于解构赋值要求等号右边是一个对象,所以如果等号右边是undefined或null,就会报错,因为它们无法转为对象。

         2、解构赋值必须是最后一个参数,否则会报错。

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

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

         4、另外扩展运算符的解构赋值,不能复制继承自原型对象的属性

    let o1 = { a: 1 };
    let o2 = { b: 2 };
    o2.__proto__ = o1;
    let { ...o3 } = o2;
    o3 // { b: 2 }
    o3.a // undefined

    上边代码中,对象o3赋值了o2,但是只复制了02自身的属性,没有复制它的原型对象o1的属性

    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

    上边代码中,变量 x 是单纯的解构赋值,所以可以读取对象 o 继承的属性;变量 y 和 z 是扩展运算符的解构赋值,只能读取对象o自身的属性,所以变量 z 可以赋值成功,变量 y 取不到值。

    5、ES6规定,变量声明语句之中,如果使用解构赋值,扩展运算符后面必须是一个变量名,而不能是一个解构赋值表达式,所以上边代码引入了中间变量newObj,如果写成下面这样会报错。

    let { x, ...{ y, z } } = o;
    // SyntaxError: ... must be followed by an identifier in declaration contexts

    6、解构赋值的一个用处,是扩展某个函数的参数,引入其他操作。

    function baseFunction({ a, b }) {
      // ...
    }
    function wrapperFunction({ x, y, ...restConfig }) {
      // 使用 x 和 y 参数进行操作
      // 其余参数做下一步处理
    }

    应用场景

    扩展运算符可以合并两个对象

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

    如果用户自定义的属性,放在扩展运算符后面,则扩展运算符内部的同名属性会被覆盖掉

    let aWithOverrides = { ...a, x: 1, y: 2 };
    // 等同于
    let aWithOverrides = { ...a, ...{ x: 1, y: 2 } };
    // 等同于
    let x = 1, y = 2, aWithOverrides = { ...a, x, y };
    // 等同于
    let aWithOverrides = Object.assign({}, a, { x: 1, y: 2 });

    这用来修改现有对象部分的属性就很方便了。

    let newVersion = {
      ...previousVersion,
      name: 'New Name' // Override the name property
    };
    未完,待续......
  • 相关阅读:
    《SQL Server 2008从入门到精通》--20180628
    2019国赛
    [蓝桥杯2020] 湖北省省赛
    2019第十届蓝桥杯B组决赛题解第五题
    试题 算法提高 分解质因数
    大数相加减
    试题 算法提高 汉诺塔
    试题 算法提高 欧拉函数
    试题 算法提高 天天向上-dp
    算法训练 猴子吃包子-构造
  • 原文地址:https://www.cnblogs.com/zhishiyv/p/14709818.html
Copyright © 2011-2022 走看看