本文参考阮一峰的《ECMAScript6入门》并结合我自身学习的知识进行总结
-
rest 参数
Rest参数接收函数的多余参数,组成一个数组,放在形参的最后,形式如下:
function f(a, b, ...theArgs) {
// ...
}
f(1, 2, 3, 4, 5) // a=1, b=2, theArgs=[3, 4, 5]
rest参数 需要注意两点
1. rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。
// 报错 function f(a, ...b, c) { // ... }
2. 函数的length属性,不包括 rest 参数。
(function(a) {}).length // 1 (function(...a) {}).length // 0 (function(a, ...b) {}).length // 1
-
拓展运算符
扩展运算符( 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')] // [
,,] 将类数组对象转换成数组拓展运算符在以下场景非常好用
1.合并数组
// ES5 [1, 2].concat(more) // ES6 [1, 2, ...more] 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' ]
此外拓展几个好用的小技巧
// 简单的将一个数组添入另一个数组 var arr1 = [1, 2, 3]; var arr2 = [4, 5, 6]; arr1.push(...arr2); console.log(arr1); // [1, 2, 3, 4, 5, 6]
// 数组之究极为所欲为插入到指定位置的操作 var a = ['香蕉', '苹果']; var b = ['橙子', ...a, '西瓜']; console.log(b); // ["橙子", "香蕉", "苹果", "西瓜"]
// 数组之终极快速复制 var a = ['香蕉', '苹果']; var b = [...a]; console.log(b); // ["香蕉", "苹果"]
2.与解构赋值结合
// ES5 a = list[0], rest = list.slice(1) // ES6 [a, ...rest] = list 下面是另外一些例子。 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 // []
如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。
const [...butLast, last] = [1, 2, 3, 4, 5]; // 报错 const [first, ...middle, last] = [1, 2, 3, 4, 5]; // 报错
3. 函数的返回值
JavaScript 的函数只能返回一个值,如果需要返回多个值,只能返回数组或对象。扩展运算符提供了解决这个问题的一种变通方法。
var dateFields = readDateFields(database); var d = new Date(...dateFields);
上面代码从数据库取出一行数据,通过扩展运算符,直接将其传入构造函数Date。
4. 字符串
扩展运算符还可以将字符串转为真正的数组。
[...'hello'] // [ "h", "e", "l", "l", "o" ]
上面的写法,有一个重要的好处,那就是能够正确识别 32 位的 Unicode 字符。
'x\uD83D\uDE80y'.length // 4 [...'x\uD83D\uDE80y'].length // 3
上面代码的第一种写法, JavaScript 会将 32 位 Unicode 字符,识别为 2 个字符,采用扩展运算符就没有这个问题。因此,正确返回字符串长度的函数,可以像下面这样写。
function length(str) { return [...str].length; } length('x\uD83D\uDE80y') // 3
凡是涉及到操作 32 位 Unicode 字符的函数,都有这个问题。因此,最好都用扩展运算符改写。
let str = 'x\uD83D\uDE80y'; str.split('').reverse().join('') // 'y\uDE80\uD83Dx' [...str].reverse().join('') // 'y\uD83D\uDE80x'
参考链接 => link