展开运算符

java script 归纳总结 黄秉佳
文章标签: 展开运算符
810

什么是展开运算符 (...)?

  • 展开运算符 :允许一个表达式在某处展开。展开运算符在多个参数(用于函数调用)或多个元素(用于数组字面量)或者多个变量(用于解构赋值)等地方可以使 用,作用就是 展开数组或字符串为一个新数组
  • 注意 : 展开运算符不能用在对象当中,因为目前展开运算符只能在可遍历对象(iterables)可用。iterables 的实现是依靠 [Symbol.iterator] 函数,而目前只有 Array,Set,String 内置 [Symbol.iterator] 方法,而 Object 尚未内置该方法,因此无法使用展开运算符。不过 ES7 草案当中已经加入了对象展开运算符特性。

怎么在函数调用中使用 ?

  • 在 ES6 之前,我们会使用 apply 方法将一个数组展开成多个参数 :
  1. function test(a,b,c){/* code */}
  2. var args = [0,1,2];
  3. test.apply(null,args);
  • 上面代码,将 args 数组当作实参传递给了 a,b,c; 利用了 Function.prototype.apply 的特性。
  • 在 ES6 中,我们就可以更加简洁地来传递数组参数:使用 ...展开运算符就可以把 args 直接传递给 test() 函数。
  1. function test(a,b,c){/* code */}
  2. var args = [0,1,2];
  3. test(...args);

怎么在数组字面量中使用 ?

  • 在 ES6 中,我们可以直接加一个数组直接合并到另外一个数组当中:
  1. var arr1 = ['a','b','c'];
  2. var arr2 = [...arr1,'d','e'];//['a','b','c','d','e']
  • 展开运算符也可以用在 push 函数中,可以不用再用 apply() / concat() 函数来合并两个数组:
  1. var arr1 = ['a','b','c'];
  2. var arr2 = ['d','e'];
  3. arr1.push(...arr2);//['a','b','c','d','e']

怎么在解构赋值中使用 ?

  • 解构赋值也是 ES6 中的一个特性,而这个展开运算符可以用于部分情景:(解构赋值中展开运算符只能用在最后
  1. let [arg1,arg2,...arg3] = [1,2,3,4];
  2. console.log(arg1);//1
  3. console.log(arg2);//2
  4. console.log(arg3);//3,4
  • 注意 : 解构赋值中展开运算符只能用在最后:
let [arg1,...arg2,arg3] = [1, 2, 3, 4]; //报错

类数组对象变成数组 ?

  • 展开运算符可以将一个 类数组对象 变成一个真正的 数组对象
  1. let list = document.querySelectorAll('div');
  2. let arr = [...list];

总结一些常见的应用场景 ?


  • 复制数组 :
  1. const fruits = ['apple','orange','banana'];
  2. const fruitsCopied = [...fruits];//['apple','orange','banana']
  3. console.log(fruits === fruitsCopied);//false
  4. //ES5中的方法:old way
  5. fruits.map(fruit => fruit);

注意 :…在展开基本数据类型时,是深copy,基本数据类型位于栈区;如果使用展开运算符 展开一个对象时,那么是浅copy,对象位于堆区;如果数组中是基本数据类型深copy;如果数组中有对象,就是浅copy;展开对象 对象就一层,是深copy;展开对象 对象是多层,是浅copy;可以通过  JSON.parse(JSON.stringify(obj)) 可以实现深copy 。

  • 数组去重 :
  1. const fruits = ['apple', 'orange', 'banana', 'banana'];
  2. const uniqueFruits = [...new Set(fruits)]; // ['apple', 'orange', 'banana']
  3. // old way
  4. fruits.filter((fruit, index, arr) => arr.indexOf(fruit) === index);
  • 合并数组 :
  1. const fruits = ['apple', 'orange', 'banana'];
  2. const vegetables = ['carrot'];
  3. const fruitsAndVegetables = [...fruits, ...vegetables]; // ['apple', 'orange', 'banana', 'carrot']
  4. const fruitsAndVegetables = ['carrot', ...fruits]; // ['carrot', 'apple', 'orange', 'banana']
  5. // 老方法
  6. const fruitsAndVegetables = fruits.concat(vegetables);
  7. fruits.unshift('carrot');
  • 将参数作为数组进行传递 :

  1. const mixer = (x, y, z) => console.log(x, y, z);
  2. const fruits = ['apple', 'orange', 'banana'];
  3. mixer(...fruits); // 'apple', 'orange', 'banana'
  4. // 老方法
  5. mixer.apply(null, fruits);
  • 数组切片 :
  1. const fruits = ['apple', 'orange', 'banana'];
  2. const [apple, ...remainingFruits] = fruits; // ['orange', 'banana']
  3. // 老方法
  4. const remainingFruits = fruits.slice(1);
  • 将参数转换为数组 :

  1. const mixer = (...args) => console.log(args);
  2. mixer('apple'); // ['apple']
  • 将 NodeList (类数组)转换为数组 :
  1. [...document.querySelectorAll('div')];
  2. // 老方法
  3. Array.prototype.slice.call(document.querySelectorAll('div'));
  • 复制对象 :
  1. const todo = { name: 'Clean the dishes' };
  2. const todoCopied = { ...todo }; // { name: 'Clean the dishes' }
  3. console.log(todo === todoCopied); // false
  4. // 老方法
  5. Object.assign({}, todo);
  • 合并对象 :
  1. const todo = { name: 'Clean the dishes' };
  2. const state = { completed: false };
  3. const nextTodo = { name: 'Ironing' };
  4. const merged = { ...todo, ...state, ...nextTodo }; // { name: 'Ironing', completed: false }
  5. // 老方法
  6. Object.assign({}, todo, state, nextTodo);
  • 将字符串拆分为字符 :
  1. const country = 'USA';
  2. console.log([...country]); // ['U', 'S', 'A']
  3. // 老方法
  4. country.split('');
  • 求最大值 / 最小值 :
  1. let numbers = [9, 4, 7, 1];
  2. Math.max(...numbers); // 9
  3. Math.min(...numbers); // 1

 

还能输出{{restrictNumber}}个字符  
  • {{reply.author}}

    {{CommonUtil.formateDate(reply.ac_CommentDate).shortTime}}
  • 回复了{{Comments.author}} :