扩展运算符

扩展运算符用3个点表示(…),用于将一个数组或类数组对象转换为用逗号分隔的值序列。
基本用法是拆解数组和字符串:

  1. const array = [1, 2, 3, 4];
  2. console.log(...array); // 1 2 3 4
  3. const str = "string";
  4. console.log(...str); // s t r i n g

(1)代替apply()函数

扩展运算符可以代替apply()函数,将数组转换为函数参数。

  1. let arr = [1, 4, 6, 8, 2];
  2. console.log(Math.max.apply(null, arr)); // 8
  3. // 利用扩展运算符简化代码:
  4. console.log(Math.max(...arr)); // 8
  5. function add (num1, num2) {
  6. return num1 + num2;
  7. }
  8. const arr = [1, 3];
  9. add.apply(null, arr); // 4
  10. // 利用扩展运算符简化代码:
  11. add(...arr); // 4

(2)代替concat()函数合并数组

  1. // concat写法:
  2. let arr1 = [1, 2, 3];
  3. let arr2 = [4, 5, 6];
  4. console.log(arr1.concat(arr2)); // [ 1, 2, 3, 4, 5, 6 ]
  5. // 扩展运算符写法:
  6. console.log([...arr1, ...arr2]); // [ 1, 2, 3, 4, 5, 6 ]

(3)转换Set,得到去重的数组

  1. // 可以使用扩展运算符将Set结构转换成数组。
  2. let arr = [1, 2, 4, 6, 2, 7, 4];
  3. console.log([...new Set(arr)]); // [ 1, 2, 4, 6, 7 ]

(4)浅拷贝(克隆)

使用扩展运算符对数组或对象进行克隆时,如果数组的元素或者对象的属性是基本数据类型,则支持深克隆;如果是引用数据类型,则是浅克隆。归根结底是因为引用数据类型的克隆只是复制了引用的地址,克隆后的对象仍然共享同一个引用地址。

  1. let obj = {
  2. name: 'kingx',
  3. address: {province: 'guangdong', city: 'guangzhou'}
  4. };
  5. let obj2 = {...obj3};
  6. obj2.name = 'kingx3'; // 不会影响基本类型的值
  7. obj2.address.city = 'shenzhen'; // 但是会影响对象
  8. console.log(obj);// {name: "kingx", address: {province: "guangdong", city: "shenzhen"}}
  1. let arr1 = [1, 3, 4, 6]; // 可以进行深克隆
  2. let arr2 = [1, 3, [4, 6]]; // 不可以进行深克隆

rest运算符

rest运算符同样使用3个点表示(…),其作用与扩展运算符相反,用于将以逗号分隔的值序列转换成数组。

(1)rest运算符与解构组合使用

使用rest运算符进行解构,则rest运算符对应的变量应该放在最后一位,否则就会抛出异常;因为如果rest运算符不是放在最后一位,变量并不知道要读取多少个数值。

  1. let arr = ['one', 'two', 'three', 'four'];
  2. let [arg1, ...arg2] = arr;
  3. console.log(arg1); // one
  4. console.log(arg2); // [ 'two', 'three', 'four' ]
  1. let {x, y, ...z} = {x: 1, y: 2, a: 3, b: 4};
  2. console.log(x); // 1
  3. console.log(y); // 2
  4. console.log(z); // {a: 3, b: 4}

(2)代替arguments处理函数参数

  1. // ES6之前,可以使用arguments来获取所有传递的参数
  2. function foo() {
  3. for (let arg of arguments) {
  4. console.log(arg); // 输出'one', 'two', 'three', 'four'
  5. }
  6. }
  7. foo('one', 'two', 'three', 'four');
  8. // 使用...
  9. function foo(...args) {
  10. for (let arg of args) {
  11. console.log(arg); // 输出'one', 'two', 'three', 'four'
  12. }
  13. }
  14. foo('one', 'two', 'three', 'four');

区别

扩展运算符和rest运算符,其实两者是互为逆运算的,扩展运算符是将数组分割成独立的序列,而rest运算符是将独立的序列合并成一个数组。

模板字符串

使用加号(+)做拼接字符串,但是拼接出来的字符串会丢失掉代码缩进和换行符。
使用模板字符串语法,会保留字符串内部的空白、缩进和换行符。

  1. // 传统字符串方案
  2. var str = 'Hello, my name is kingx, ' +
  3. 'I am working in Beijng.';
  4. console.log(str); // Hello, my name is kingx, I am working in Beijng.
  5. let str2 = `Hello, my name is kingx,
  6. I am working in Beijng.`;
  7. console.log(str2);
  8. // Hello, my name is kingx,
  9. I am working in Beijng.
  1. // 数学运算
  2. let x = 1,
  3. y = 2;
  4. console.log(`${x} + ${y * 2} = ${x + y * 2}`); // 1 + 4 = 5
  5. // 属性引用和数学运算
  6. let obj = {x: 1, y: 2};
  7. console.log(`${obj.x + obj.y}`); // 3
  8. // 函数调用
  9. function fn() {
  10. return "Hello World";
  11. }
  12. console.log(`foo ${fn()} bar`); // foo Hello World bar