ES6中rest参数与拓展运算符
2017-11-25 本文已影响0人
Ohbug
本文参考阮一峰的《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')] // [<div>, <div>, <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