美文网首页
ES6 中三个点的两种用法

ES6 中三个点的两种用法

作者: 楼顶吹吹风 | 来源:发表于2020-03-18 14:43 被阅读0次

    前言

    对于ES6扩展运算符和rest参数用的不多的同学来说,有时候看别人的源码很容易将三个点(...)的用法混淆。因为都是一样的三个点,只是用在不同的地方就会有不同的作用。本文将这两个用法放在一起,方便对比记忆。

    参考: ES6入门

    rest参数(函数的扩展)

    • 形式:...变量名
    • 作用:用于获取函数任意数目的参数,这样就不需要使用arguments对象了,rest参数对应的是一个数组。当传入的参数个数不确定时,这个运算符就能发挥作用了。比如我定义了一个函数,允许传入1~100个值,我不确定调用时会传入多少个值的时候。
    • 怎么判断是正运算?正运算是属于函数的扩展,所以当看到三个点用于形参,而且后面的变量名并没有预先定义时,就是rest参数的用法,用来获取参数的。
    • arguments对象不是数组,而是一个类似数组的对象。所以为了使用数组的方法,必须使用Array.prototype.slice.call先将其转为数组。rest参数显得简洁得多。
    // arguments变量的写法
    function sortNumbers() {
      return Array.prototype.slice.call(arguments).sort();
    }
    
    // rest参数的写法
    const sortNumbers = (...numbers) => numbers.sort();
    

    扩展运算符(相当于rest参数的逆运算)

    • 形式:...数组变量名
    • 作用:将一个数组转为用逗号分隔的参数序列。由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。
    • 当三个点出现在预先定义好的数组变量前面时,就能判断是扩展运算符了。
    // ES5 的写法
    function f(x, y, z) {
      // ...
    }
    var args = [0, 1, 2];
    f.apply(null, args);
    
    // ES6的写法
    function f(x, y, z) {
      // ...
    }
    let args = [0, 1, 2];
    f(...args);
    
    扩展运算符的应用
    1. 复制数组:数组是复合的数据类型,直接复制的话,只是复制了数组的指针,而不是克隆一个全新的数组。修改其中一个数组,会直接导致另一个数组的变化。
    ES5 只能用变通方法来复制数组。
    const a1 = [1, 2];
    const a2 = a1.concat();
    
    
    扩展运算符提供了复制数组的简便写法。
    const a1 = [1, 2];
    // 写法一
    const a2 = [...a1];
    // 写法二
    const [...a2] = a1;
    
    1. 合并数组:不过,这两种方法都是浅拷贝,它们的成员都是对原数组成员的引用,如果修改了原数组的成员,会同步反映到新数组。
    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' ]
    
    1. 与解构赋值: 如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。
    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   // []
    
    1. 字符串:
    [...'hello']                  // [ "h", "e", "l", "l", "o" ]
    
    1. 实现了Iterator接口的对象
    2. Map和Set结构,Generator函数

    总结

    • 两者的作用:
      • rest参数用于获取函数任意数目的参数,获取的参数会自动装入运算符后面的变量。
      • 扩展运算符用于将一个数组转为用逗号分隔的参数序列。
    • 如何判断是rest参数还是扩展运算符
      • 三个点用于形参时就是rest参数运算符
      • 其他情况均是扩展运算符。
      • 可以看出,大部分情况都是扩展运算符的用法,所以我们看代码时并不用那么小心翼翼。

    相关文章

      网友评论

          本文标题:ES6 中三个点的两种用法

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