本文介绍ES6引入的剩余参数(Rest Parameters)语法,通过三个点前缀接收多余实参。对比其与arguments对象的差异,说明剩余参数为真数组且不含length属性中的剩余项,同时强调剩余参数后不可再定义普通参数,且不能与arguments混用。
剩余参数基本用法
在JavaScript函数内部,存在一个arguments对象用于获取所有传入的实参。ES6引入了剩余参数(Rest Parameters)机制,允许函数接收除指定参数外的其余所有参数。
剩余参数是一个由开发者自定义的普通标识符,其语法特征是在标识符前添加三个点(...)。
function func(a, ...rest) {
console.log(a)
console.log(rest)
}
func(1)
func(1, 2, 3, 4)
以函数func为例,其第二个参数rest前包含三个点。定义该函数并调用两次后,观察执行结果。

第一次调用时,rest表现为空数组;第二次调用时,rest包含元素[2, 3, 4]。
若在前置定义中指定两个参数,剩余参数的行为如下。
function func(a, b, ...rest) {
console.log(a, b)
console.log(rest)
}
func(1, 2)
func(1, 2, 3, 4)
具体的输出结果如代码所示。

通过上述两个示例,可以明确剩余参数的基本用法与意义。
剩余参数的限制
由于剩余参数用于收集剩余参数,因此在剩余参数之后不能再定义其他普通参数,否则会导致语法错误。
function func(a, ...rest, b) {
}
若在rest参数后添加参数b,Firefox浏览器会抛出错误。

对函数length属性的影响
使用剩余参数后,函数的length属性值会发生变化。
function func(a, b, ...rest) {
}
func.length // 2
此时length属性不包含剩余参数,仅计算剩余参数之前的普通参数,因此值为2。
剩余参数与arguments的关系
剩余参数前是否可以不定义任何普通参数?答案是肯定的。
function func(...rest) {
console.log(rest)
}
func(1) // [1]
func(1, 2, 3, 4) // [1,2,3,4]
此处的rest参数在功能上与arguments类似,有人或许认为这直接取代了arguments。ECMAScript标准确实有此意图,在已废弃的ES4规范中便已存在Rest Parameters(熟悉ActionScript 3的开发者应当知晓),尽管ES4最终被废弃,但Rest Parameters机制仍被保留并纳入ES6标准。
注意,剩余参数不能与arguments对象同时使用,否则会引发错误。
function func(...rest) {
console.log(rest)
console.log(arguments)
}
Firefox控制台会显示相应的报错信息。

与arguments的区别
arguments对象与剩余参数存在以下主要区别。
arguments是一个类数组对象(Array-like),而剩余参数是一个真正的数组(Array),具备Array.prototype上的所有方法。此外,arguments对象包含callee属性,callee上包含caller属性。
function func(a, ...rest) {
console.log(rest instanceof Array)
}
func(1, 2) // true
实际应用示例
最后,通过一个实际应用场景来展示剩余参数的用法。
/*
* 任意个数相加
*
* **示例**
* sum(1)
* sum(1, 2)
* sum(1, 2, 3)
*/
function sum(first, ...rest) {
var result = first
var i = 0
var len = rest.length
while (i < len) {
result += rest[i]
i++
}
return result
}
以上即为本文关于剩余参数的全部内容,希望读者能够理解并应用。