ES6(ECMAScript 2015)引入的 Rest 参数(Rest Parameters)是一种非常实用的语法特性,它允许我们将一个不确定数量的参数表示为一个数组。它的核心思想是“收集剩余的参数”。
1. 基本语法
Rest 参数使用三个点 ...
(被称为“展开运算符”或“剩余运算符”,具体含义取决于上下文)后跟一个形参名来定义。
function functionName(...restParameterName) {
// restParameterName 是一个真正的数组,包含了所有传入的额外参数
}
关键点:
- Rest 参数必须是函数参数列表中的最后一个参数。
- 它将传递给函数的所有“剩余”实参(从它所在位置开始到最后)收集到一个真正的 Array 对象中。
- 这个数组可以使用所有标准的数组方法(如
map
,filter
,reduce
,forEach
等)。
2. 解决的问题 (与 ES5 的对比)
在 ES6 之前,如果想处理任意数量的参数,通常会使用函数内部的 arguments
对象。
// ES5 方式:使用 arguments 对象
function sum() {
let total = 0;
// arguments 不是真正的数组,只是一个类数组对象
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
console.log(sum(1, 2, 3, 4)); // 10
这种方式存在几个问题:
arguments
不是真正的数组:它没有Array.prototype
上的方法(如map
,reduce
),需要先转换(如[].slice.call(arguments)
)才能使用。- 可读性差:函数签名无法清晰地表达它可以接受多个参数。
- 灵活性差:如果函数有固定参数,
arguments
包含了所有参数,区分固定和可变部分比较麻烦。
3. Rest 参数的优势与用法
示例 1:替代 arguments,实现可变参数函数
// ES6 方式:使用 Rest 参数
function sum(...numbers) { // 将所有传入的参数收集到 numbers 数组中
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
console.log(sum(5, 10)); // 15
numbers
是一个真正的数组,可以直接使用reduce
方法,代码更简洁、语义更清晰。
示例 2:结合固定参数
Rest 参数可以和固定参数一起使用,Rest 参数必须放在最后。
function multiply(factor, ...values) {
// factor 是第一个固定参数
// values 是包含剩余所有参数的数组
return values.map(value => value * factor);
}
console.log(multiply(2, 1, 2, 3, 4)); // [2, 4, 6, 8]
console.log(multiply(3, 5, 6)); // [15, 18]
- 第一个参数
2
被赋值给factor
,后面的1, 2, 3, 4
被收集到values
数组中。
示例 3:解构赋值中的 Rest 元素
Rest 参数的概念也延伸到了数组和对象的解构赋值中。
// 数组解构中的 Rest 元素
const [first, second, ...others] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(second); // 2
console.log(others); // [3, 4, 5] (一个新数组)
// 对象解构中的 Rest 属性 (ES2018)
const { name, age, ...otherInfo } = { name: 'Alice', age: 25, city: 'Beijing', job: 'Engineer' };
console.log(name); // 'Alice'
console.log(age); // 25
console.log(otherInfo); // { city: 'Beijing', job: 'Engineer' } (一个新对象)
4. 重要注意事项
- 只能有一个:一个函数参数列表中最多只能有一个 Rest 参数,并且它必须位于末尾。
- 不能有默认值:Rest 参数本身不能有默认值。
- 不能用于 setter:对象属性的 setter 函数不能有 Rest 参数。
- 箭头函数兼容:Rest 参数在箭头函数中同样适用。
总结
对 ES6 中 Rest 参数的理解可以归纳为以下几点:
- 目的:解决函数处理不定数量参数的需求,提供比
arguments
对象更优雅、更强大的方式。 - 语法:使用
...parameterName
定义,必须是函数参数列表的最后一个。 - 本质:将调用时传入的“剩余”实参收集成一个真正的数组。
- 优势:
- 得到的是真正的
Array
实例,可直接使用数组方法。 - 提升了代码的可读性和可维护性,函数签名更清晰。
- 与固定参数结合使用,逻辑分离更明确。
- 概念扩展到解构赋值中,增强了数据提取的灵活性。
- 得到的是真正的
- 应用场景:编写工具函数(如求和、求平均)、封装 API、处理回调参数等任何需要处理可变参数列表的场景。
简单来说,Rest 参数就是把“剩下的东西”打包成一个数组,是现代 JavaScript 编程中不可或缺的特性之一。
THE END