面试题:说说你对 ES6 中 rest 参数的理解?

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

这种方式存在几个问题:

  1. arguments 不是真正的数组:它没有 Array.prototype 上的方法(如 map, reduce),需要先转换(如 [].slice.call(arguments))才能使用。
  2. 可读性差:函数签名无法清晰地表达它可以接受多个参数。
  3. 灵活性差:如果函数有固定参数,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 参数的理解可以归纳为以下几点:

  1. 目的:解决函数处理不定数量参数的需求,提供比 arguments 对象更优雅、更强大的方式。
  2. 语法:使用 ...parameterName 定义,必须是函数参数列表的最后一个。
  3. 本质:将调用时传入的“剩余”实参收集成一个真正的数组
  4. 优势
    • 得到的是真正的 Array 实例,可直接使用数组方法。
    • 提升了代码的可读性和可维护性,函数签名更清晰。
    • 与固定参数结合使用,逻辑分离更明确。
    • 概念扩展到解构赋值中,增强了数据提取的灵活性。
  5. 应用场景:编写工具函数(如求和、求平均)、封装 API、处理回调参数等任何需要处理可变参数列表的场景。

简单来说,Rest 参数就是把“剩下的东西”打包成一个数组,是现代 JavaScript 编程中不可或缺的特性之一。

THE END
喜欢就支持一下吧
点赞8 分享