Rest用于收拢参数或解构左侧,Spread用于展开数组/对象或解构右侧;Rest必在参数末尾且唯一,Spread可多处使用;二者语法相同但语义相反,上下文决定行为。
Rest 和 Spread 都用 ...,但作用完全相反:Rest 是“收”,Spread 是“放”。记错位置或场景,轻则报错,重则逻辑静默失效。
... 一定是 Rest 参数它只出现在函数定义的参数列表末尾,把所有“多出来的”实参打包成一个真数组——不是类数组的 arguments,能直接调 .map()、.filter()。
SyntaxError: Rest parameter must be last formal parameter
function f(...a, ...b) 直接语法错误function log(first, ...rest) {
console.log('首项:', first); // 'a'
console.log('其余:', rest); // ['b', 'c']
}
log('a', 'b', 'c');... 一定是 Spread 运算符它把一个可迭代值(数组、字符串、Set)或对象“摊开”,把每个元素/属性逐个注入到新结构中。
Math.max(...[1, 5, 3]) ✅;Math.max([1, 5, 3]) ❌(结果是 NaN)const arr = [...arr1, ...arr2] —— 不是 [arr1, arr2](那会嵌套)
覆盖:const user = { name: 'Alice', age: 30 };
const updated = { ...user, age: 31, city: 'Beijing' }; // { name: 'Alice', age: 31, city: 'Beijing' }... 的角色取决于它在等号左边还是右边这是最容易混淆的点:同一符号,在解构左侧是 Rest,在右侧是 Spread。
立即学习“Java免费学习笔记(深入)”;
const [a, b, ...rest] = [1, 2, 3, 4] → rest 是 [3, 4]
const nums = [2, 3]; const all = [1, ...nums, 4] → [1, 2, 3, 4]
const { id, ...data } = { id: 1, name: 'x', role: 'admin' } → data 是 { name: 'x', role: 'admin' }
真正卡住人的往往不是语法,而是没意识到 ... 的行为完全由它所处的上下文决定:参数定义?→ Rest;调用/字面量/解构右侧?→ Spread;解构左侧?→ Rest。写错位置,JS 解析器不会猜你意图,只会报错或产出意外结果。