ES6中为我们加入了一种有趣语法,(...)在ES6中被称为扩展运算符,它可以对某个实现有iterator接口的对象进行展开运算,但是Object对象却不在这范围之内,这点确实给这种语法带来了很多不便,幸运的是,ES6开放了迭代接口的编写,所以我们可以弥补这个缺点,我在这一章中,本次主要分享(...)语法,下章再分享迭代的实现。
我们先来看看扩展运算符的使用例子。
//ES 5的写法
var str = "这里是一段中文!";
var first = [1, 2, 3];
var last = [4, 5, 6];
console.log(str.split("").join(" ")) //这 里 是 一 段 中 文 !
console.log(first.concat(last)); //[ 1, 2, 3, 4, 5, 6]
//ES 6的写法
let str = "这里是一段中文!";
let first = [1, 2, 3];
let last = [4, 5, 6];
console.log(...str); //这 里 是 一 段 中 文 !
console.log([...first, ...last]); //[ 1, 2, 3, 4, 5, 6]
我们看到ES6的扩展运算会把有迭代接口的对象进行逐个拆分开来,可能上面的例子不直观,感觉扩展运算符只是让我们少写了两个函数而已,现在我们来看看扩展运算符真实的威力!
//示例1:
let arr = [1];
let [first, ...last] = arr;
console.log(first, last); //1, []
//示例2:
let arr = [1, 2, 3, 4, 5, 6];
let [,,,...last] = arr;
console.log(last); //[4, 5, 6]
//示例3:
let user = { id : 1, name : 'test', roles : ['admin', 'test', 'dbAdmin'] };
let { roles : [,...role] } = user;
let { name : [...name] } = user;
console.log(role); //['test', 'dbAdmin']
console.log(name); //['t', 'e', 's', 't']
配合解构来使用扩展运算符,可以匹配取到我们想要的任何值,但是值得注意的是,我们扩展运算符是不能对Object进行操作的,比如:
let user = { id : 1, name : 'test', roles : ['admin', 'test', 'dbAdmin'] };
let result = { ...user }; //SyntaxError: Unexpected token ...
在上述示例1、示例2、示例3中的操作方式,被ES6称为逆运算,在逆运算中,值得注意的是,逆运算后面不能在有任何解构表示法,因为逆运算会将前者模式匹配出来的值放入到扩展运算中,如果后面还有解构模式或者逆运算,ES6不知道你前者逆运算是否是误写,例子如下:
//示例1:
let arr = [1, 2, 3, 4, 5, 6];
//报错,这种语法是矛盾的,如果first是arr所有的元素,则last取不到任何元素。
let [...first, ...last] = arr;
//示例2:
let arr = [1, 2, 3, 4, 5, 6];
//报错,道理是一样的,first匹配arr所有元素,则last匹配不到最后一个元素。
let [...first, last] = arr;
接下来,我们看看REST参数,ES6中(...)语法也允许在函数形参中使用,这种语法被称为REST参数,我们来看看REST参数使用。
//示例1:
function concat(...value){
return value.join('');
}
concat("你","好",",","领","域", "!"); //你好,领域!
concat(4, 5, 6,); //456
//示例2:
function push(me, ...args){
return me.concat(args.join(''));
}
let result = push("你好",",","领","域","!");
console.log(result); //你好,领域!
//示例3:
function max(a, b){
return Math.max(a, b);
}
max(...[4, 6]);
//示例4:
function sum(a, b, c, d, e, f, g){
return a + b + c + d + e + f + g;
}
sum(1, 2, ...[3, 4], 5, ..[6, 7]);
上述代码中,示例1、2是使用的REST参数,示例3、4是一般的扩展运算符,扩展运算符是允许将数组变为参数序列的,有一点很重要,REST参数也遵循上述规则,不能在REST参数后面有另一个REST参数或者形参,比如:
//报错,因为args会将所有形参第2个开始,合并在args里面,而...val是无法匹配的。
function push(me, ...args, ...val) {
}
//报错,同样的道理,第2个形参开始,组装到合并args里面,val是无法匹配的。
function push(me, ...args, val){
}