• ES6"..."扩展运算符


    在数组中的应用

    扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,++将一个数组转为用逗号分隔的参数序列++。

    console.log(...[1, 2, 3])
    // 1 2 3
    
    console.log(1, ...[2, 3, 4], 5)
    // 1 2 3 4 5
    
    [...document.querySelectorAll('div')]
    // [<div>, <div>, <div>]
    

    扩展运算符与正常的函数参数可以结合使用,非常灵活。

    function f(v, w, x, y, z) { }
    const args = [0, 1];
    f(-1, ...args, 2, ...[3]);
    
    // ES6的写法
    function f(x, y, z) {
      // ...
    }
    let args = [0, 1, 2];
    f(...args);
    

    扩展运算符后面还可以放置表达式。

    const arr = [
      ...(x > 0 ? ['a'] : []),
      'b',
    ];
    

    通过push函数,将一个数组添加到另一个数组的尾部。

    ES5 写法中,push方法的参数不能是数组,所以只好通过apply方法变通使用push方法。有了扩展运算符,就可以直接将数组传入push方法。

    // ES5的 写法
    var arr1 = [0, 1, 2];
    var arr2 = [3, 4, 5];
    Array.prototype.push.apply(arr1, arr2);
    
    // ES6 的写法
    let arr1 = [0, 1, 2];
    let arr2 = [3, 4, 5];
    arr1.push(...arr2);
    

    通过扩展运算符,生成日期

    // ES5
    new (Date.bind.apply(Date, [null, 2015, 1, 1]))
    // ES6
    new Date(...[2015, 1, 1]);
    

    复制数组

    a1会返回原数组的克隆,再修改a2就不会对a1产生影响。

    //es5
    const a1 = [1, 2];
    const a2 = a1.concat();
    a2[0] = 2;
    a1 // [1, 2]
    
    //es6
    const a1 = [1, 2];
    // 写法一
    const a2 = [...a1];
    // 写法二
    const [...a2] = a1;
    

    合并数组

    这两种方法都是浅拷贝

    const arr1 = ['a', 'b'];
    const arr2 = ['c'];
    const arr3 = ['d', 'e'];
    
    // ES5 的合并数组
    arr1.concat(arr2, arr3);
    // [ 'a', 'b', 'c', 'd', 'e' ]
    
    // ES6 的合并数组
    [...arr1, ...arr2, ...arr3]
    // [ 'a', 'b', 'c', 'd', 'e' ]
    

    与解构赋值结合

    如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

    const [first, ...rest] = [1, 2, 3, 4, 5];
    first // 1
    rest  // [2, 3, 4, 5]
    
    const [first, ...rest] = [];
    first // undefined
    rest  // []
    
    const [first, ...rest] = ["foo"];
    first  // "foo"
    rest   // []
    

    字符串

    扩展运算符还可以将字符串转为真正的数组。

    [...'hello']
    // [ "h", "e", "l", "l", "o" ]
    

    实现了 Iterator 接口的对象

    querySelectorAll方法返回的是一个NodeList对象。它不是数组,而是一个类似数组的对象。这时,扩展运算符可以将其转为真正的数组,原因就在于NodeList对象实现了 Iterator 。

    let nodeList = document.querySelectorAll('div');
    let array = [...nodeList];
    

    Map 和 Set 结构,Generator 函数

    扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符,比如 Map 结构。

    let map = new Map([
      [1, 'one'],
      [2, 'two'],
      [3, 'three'],
    ]);
    
    let arr = [...map.keys()]; // [1, 2, 3]
    

    对象的扩展

    解构赋值

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

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

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

    let { ...x, y, z } = someObject; // 句法错误
    let { x, ...y, ...z } = someObject; // 句法错误
    

    解构赋值的拷贝是浅拷贝,解构赋值拷贝的是这个值的引用

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

    拷贝对象

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

    合并两个对象

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

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

    a对象的x属性和y属性,拷贝到新对象后会被覆盖掉。

    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
    };
    

    如果把自定义属性放在扩展运算符前面,就变成了设置新对象的默认属性值。

    let aWithDefaults = { x: 1, y: 2, ...a };
    // 等同于
    let aWithDefaults = Object.assign({}, { x: 1, y: 2 }, a);
    // 等同于
    let aWithDefaults = Object.assign({ x: 1, y: 2 }, a);
    
  • 相关阅读:
    js函数对象
    jQuery选择器
    js数组
    js知识点
    正则|数字|Format
    Ajax基础
    MVC 打包压缩
    JS(正则|JSON)
    CLR via C#
    Exists/In/Any/All/Contains操作符
  • 原文地址:https://www.cnblogs.com/eternityz/p/12272399.html
Copyright © 2020-2023  润新知