1. Rest 解构赋值(...运算符解构赋值)

  • Rest 解构赋值必须是最后一个参数,否则会报错

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

let [a, b, ...c] = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(a, b, c);  // 1, 2, [4, 5, 6, 7, 8]

  • Rest 解构赋值的错误示范

let {x, y, ...z} = null;  // 运行时错误
let {x, y, ...z} = undefined;  // 运行时错误

// Rest 解构赋值必须是最后一个参数,否则会报错
let {...x, y, z} = {a: 1, b: 2, c: 3};  // 句法错误
let {x, ...y, ...z} = {a: 1, b: 2, c: 3};  // 句法错误

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

let obj = {a: {b: 1'+'}'+'}'}};
let {...r} = obj;

obj.a.b = 2;

console.log(
    obj.a.b,  // 2
    r.a.b  // 2
);

2. 扩展运算符(...)

  • 作用: 用于取出参数对象的所有可遍历属性,拷贝到当前对象之中

let j = {a: 3, b: 4};
let n = {...j};  // { a: 3, b: 4 }

// 等同于

let aClone = Object.assign({}, j);  // 合并对象 { a: 3, b: 4 }

  • 扩展运算符可以用于合并多个对象

let ab = {a1: 1, b1: 2};
let cd = {c1: 3, d1: 4};
let abcd = {...ab, ...cd};  // {a1: 1, b1: 2, c1: 3, d1: 4}

// 等同于

let abcdClone = Object.assign({}, ab, cd);  // 合并对象 {a1: 1, b1: 2, c1: 3, d1: 4}

  • 当有相同的值时候后面的值会覆盖前面的值

let cover = {
    a2: 'a2',
    b2: 'b2',
    c2: 'c2',
    d2: 'd2',
};

let expansionCover = {
    a2: 'a1',
    b2: 'b1',
    ...cover,
    e: 'e1'
};  // {a2:'a2', b2:'b2', c2:'c2', d2:'d2'}

  • 扩展运算符 对象 和 数组 用法一样

let aArr = [4, 5, 6];
let dArr = [1, 2, ...aArr, 7];  // [1, 2, 4, 5, 6, 7]