语言基础

发布于 2026-08-31

Rest

Rest is a JavaScript feature that allows you to pass a variable number of arguments to a function.

混淆点

... 不是一个固定语法,本身也不代表"某个功能",它是一种语法标记。

决定它是展开(spread)还是剩余(rest)的,是它出现的位置和上下文。

...something
 
1 Spread 展开
 
2 Rest 收集

Spread 展开 把"一个整体"拆开

用在数组字面量、函数调用参数、对象字面量中,作用是把一个可迭代对象(数组、字符串、Map/Set等)或对象"摊开"成一个个独立的元素。

// 1. 数组展开:把一个数组拆成散开的元素
const arr1 = [1, 2, 3];
const arr2 = [0, ...arr1, 4]; // [0, 1, 2, 3, 4]
 
// 2. 函数调用时展开:把数组拆成一个个参数
function sum(a, b, c) { return a + b + c; }
sum(...[1, 2, 3]); // 等价于 sum(1, 2, 3)
 
// 3. 对象展开(ES2018):把对象的键值对铺开合并
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
 
// 4. 常见实战用法:浅拷贝、合并
const copy = [...arr1];        // 数组浅拷贝
const merged = { ...obj1, ...obj2 }; // 对象合并(后面覆盖前面)

对象的处理:

cosnt user = {
    name: "Ocean",
    age: 18,
}
 
const newUser = {
    ...user,
    gender: "male",
}
 
// 相当于
const finalUser = {
    name: "Ocean",
    age: 18,
    gender: "male",
}

spread 永远发生在"构造一个新东西"的时候(新数组、新对象、函数调用),它在消费/使用已有的数据。

Rest Parameters 剩余参数,收集剩余函数参数

用在函数参数列表中,把没有被显式命名的参数收集成一个数组。必须是最后一个参数。

function myFunc(first, second, ...rest) {
  console.log(first);  // 1
  console.log(second); // 2
  console.log(rest);   // [3, 4, 5]
}
myFunc(1, 2, 3, 4, 5);
 
// 常见实战:替代 arguments 对象,写法更现代
function sum(...nums) {
  return nums.reduce((a, b) => a + b, 0);
}

Rest in Destructuring 剩余模式,解构时收集"剩下的"

用在解构赋值(数组解构 / 对象解构)的左边,把没被取走的部分收集起来。其实是"剩余参数"概念在解构场景里的延伸,所以也叫 rest。

// 数组解构 + rest
const [first, second, ...others] = [1, 2, 3, 4, 5];
// first = 1, second = 2, others = [3, 4, 5]
 
// 对象解构 + rest
const { a, b, ...restObj } = { a: 1, b: 2, c: 3, d: 4 };
// a = 1, b = 2, restObj = { c: 3, d: 4 }
 
// 实战:常用于过滤掉某些属性
function omitPassword(user) {
  const { password, ...safeUser } = user;
  return safeUser; // 返回不含 password 的对象
}

区别

名称出现位置作用方向
Spread(展开)数组/对象字面量中、函数调用的参数中把一个整体拆成多个元素一 → 多(读取时)
Rest(剩余参数)函数定义的参数列表末尾把多个实参收集成一个数组多 → 一(定义时)
Rest(剩余解构)解构赋值的左边末尾把解构后剩下的部分收集成一个新对象/数组多 → 一(赋值时)

问一个问题:这段代码是在"造"一个新数组/对象,还是在"拆"一个已有的东西?

  • 如果代码是 [...x]、{...x}、f(...x) —— 这是在用 x 的内容去构造别的东西 → spread
  • 如果代码是 function f(...x)、const [a, ...x] = arr —— 这是在定义一种接收模式,把"剩下的东西"装进 x → rest

换句话说:spread 在"值"的位置上,rest 在"变量声明/参数声明"的位置上。