首先点明,ES6的新特性之扩展运算符(spread)就是三个点(...),和ES6的可变参数形式一样。
扩展运算符是很强大的一个运算符,它能简化很多在ES5中会比较繁杂的操作。对于这个运算符,概念性的东西不多,所以这里我就简明扼要的给出一些它的常用场景:
1:可变参数。
(虽然可变参数严格说不是扩展运算符(spread),而是剩余运算符(rest),但是鉴于它也是三个点:...,我就写在了一起以便记忆)
//例一: function add(...values) { let sum = 0; for (var val of values) { sum += val; } return sum; } add(2, 5, 3) // 10 //例二: // arguments变量的写法 function sortNumbers() { return Array.prototype.slice.call(arguments).sort(); } // rest参数的写法 const sortNumbers = function(...numbers){ return numbers.sort(); }arguments对象不是数组,而是一个类似数组的对象。
所以为了使用数组的方法,必须使用Array.prototype.slice.call先将其转为数组。
rest 参数就不存在这个问题,它就是一个真正的数组,数组特有的方法都可以使用。
//既然说到了可变参数,就再举个例子吧: //例三: function push(array, ...items) { items.forEach(function(item) { array.push(item); console.log(item); }); } var a = []; push(a, 1, 2, 3) //注意,可变参数只能出现在最后一个参数位置
2.展开数组:
由于扩展运算符可以展开数组,所以不再需要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);下面是扩展运算符取代apply方法的一个实际的例子,应用Math.max方法,简化求出一个数组最大元素的写法。
//例二: // ES5 的写法 Math.max.apply(null, [14, 3, 77]) // ES6 的写法 Math.max(...[14, 3, 77]) // 等同于 Math.max(14, 3, 77);3.复制数组:
数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。
const a1 = [1, 2]; const a2 = a1; a2[0] = 2; a1 // [2, 2] //ES5只能用变通的方法来复制数组 const a1 = [1,2]; const a2 = a1.concat(); //扩展运算符提供了复制数组的简便方法 //其实也用到了其展开数组的功能。 const a1 = [1,2]; //法一: const a2 = [...a1]; //法二:用到了解构复制的相关知识 const [...a2] =a1;4.合并数组:
var arr1 = ['a', 'b']; var arr2 = ['c']; var arr3 = ['d', 'e']; // ES5的合并数组 arr1.concat(arr2, arr3); // [ 'a', 'b', 'c', 'd', 'e' ] // ES6的合并数组 [...arr1, ...arr2, ...arr3] // [ 'a', 'b', 'c', 'd', 'e' ]
5.与解构赋值结合:
扩展运算符可以与解构赋值结合起来,用于生成数组。
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 // [] /* 如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。 */
6.将字符串转化为真正的数组:
其实,任何实现了Iterator接口的对象都可用扩展运算符转化为真正的数组。
比如:arguments对象。
//例: [...'hello'] // [ "h", "e", "l", "l", "o" ]
备注:在ES2017中,对象操作中也可结合扩展运算符。不过,这里不举例子了,如果想了解详情,请参考阮一峰老师的<<ECMAScript6入门>>关于对象的章节