ES6学习——新的语法:Rest

来源:互联网 发布:好看的韩剧 知乎 编辑:程序博客网 时间:2024/05/21 06:12

Rest操作符和Spread操作都是用三个点(...)表示,但作用整好相反。Rest操作符一般用在函数参数的声明中,而Spread用在函数的调用中。

下面看个例子:

'use strict';function func(...args){console.log(args);//[1,2,3,4]}func(1,2,3,4);

我们知道在strict mode下,对arguments做了很多限制,而且arguments是个arrayLike对象,不能像操作数组那样直接操作它。但用Rest操作符以后,args参数就是一个数组了,任何操作数组的方法都可以直接对args使用。

console.log(Object.prototype.toString.call(args));//[object Array]

在看个例子:

'use strict';function f(x, ...y) {console.log(x,y);//a,["b","c"]}f('a', 'b', 'c');        f('a')//x='1',y=[]        f()//x=undefined,y=[]

上面的两个例子都是把Rest操作符放在了函数形参的最后,那么,Rest操作符能不能应用在函数形参的其它位置呢?答案是:No

function f(x, ...y,z) {//Uncaught SyntaxError: Rest parameter must be last formal parameterconsole.log(x,y,z);}f('a', 'b', 'c'); 

其实也很好理解,Rest单词的意思就是剩余的,把剩余的都归集到一起,所以上面的z形参就没什么作用了。但是我在ES6的规范(14.1 Function Definitions)中并没有找到这种语法错误。


在规范的13.3.3.6的最后有对函数参数中使用Rest操作的说明:

BindingRestElement : ... BindingIdentifier
1. Let lhs be ResolveBinding(StringValue of BindingIdentifier, environment).
2. ReturnIfAbrupt(lhs).
3. Let A be ArrayCreate(0).
4. Let n=0.
5. Repeat,
    a. If iteratorRecord.[[done]] is false,
        i. Let next be IteratorStep(iteratorRecord.[[iterator]]).
        ii. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
        iii. ReturnIfAbrupt(next).
        iv. If next is false, set iteratorRecord.[[done]] to true.  
    b. If iteratorRecord.[[done]] is true, then
        i. If environment is undefined, return PutValue(lhs, A).
        ii. Return InitializeReferencedBinding(lhs, A).
    c. Let nextValue be IteratorValue(next).
    d. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to true.
    e. ReturnIfAbrupt(nextValue).
    f. Let status be CreateDataProperty(A, ToString (n), nextValue).
    g. Assert: status is true.
    h. Increment n by 1.


*以上全部代码在Chrome 47下通过测试

0 0