11.4 剩余参数( Rest parameters )
将剩余操作符(...)放在最后一个形参的前面意味着该形参会接收到所有剩下的实参(这些实参放置在一个数组中,然后传给这个形参)。
function f(x, ...y) {
···
}
f('a', 'b', 'c'); // x = 'a'; y = ['b', 'c']
如果没有剩余的参数,剩余参数将会被设置为空数组:
f(); // x = undefined; y = []
扩展操作符(...)看起来和剩余操作符一模一样,但是它用于函数调用和数组字面量(而不是在解构模式里面)。
11.4.1 禁止再使用 arguments
!
剩余参数可以完全替代 JavaScript 的臭名昭著的特殊变量 arguments
。剩余参数的优点是它总是数组:
// ECMAScript 5: arguments
function logAllArguments() {
for (var i=0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
// ECMAScript 6: rest parameter
function logAllArguments(...args) {
for (let arg of args) {
console.log(arg);
}
}
11.4.1.1 混合解构过程和访问解构值
一个有趣的 arguments
的特性就是定义普通参数的同时,也会拿到所有参数的一个数组:
function foo(x=0, y=0) {
console.log('Arity: '+arguments.length);
···
}
在这种情形下,如果将一个剩余参数和数组解构结合起来,就可以避免使用 arguments
了。最终的代码相对较长,但是更加清晰:
function foo(...args) {
let [x=0, y=0] = args;
console.log('Arity: '+args.length);
···
}
这对命名参数也有效(可选对象):
function bar(options = {}) {
let { namedParam1, namedParam2 } = options;
···
if ('extra' in options) {
···
}
}
11.4.1.2 arguments
是可迭代的
在 ECMAScript 6 中, arguments
是可迭代的,这意味着你可以使用 for-of
循环和扩展操作符:
> (function () { return typeof arguments[Symbol.iterator] }())
'function'
> (function () { return Array.isArray([...arguments]) }())
true