展开运算符…是语法糖,用于将可迭代对象“打散”为独立元素,支持数组拼接、对象合并、函数传参等,但仅浅拷贝且要求操作对象可迭代。

javaScript 展开运算符 ... 不是函数,也不是方法,而是一种语法糖——它把可迭代对象(比如数组、字符串、Set、map)“打散”成独立元素,让数据操作更直觉。它和剩余参数(...rest)长得一样,但方向相反:一个是“拆”,一个是“收”。
合并数组或对象时,为什么用 [...arr1, ...arr2] 而不是 concat()?
因为写法更紧凑、可读性更高,且支持在任意位置插入元素或字面量。
-
[...arr1, 99, ...arr2]可直接在中间插值,concat()做不到 - 对象合并更自然:
{ ...obj1, name: 'Alice', ...obj2 },后者同名属性自动覆盖前者 - 不修改原数组/对象,符合函数式编程习惯
- 注意:对象展开只适用于普通对象,不能对
NULL或undefined直接展开,否则报TypeError: Cannot spread non-iterable instance
传参给函数时,math.max(...nums) 比 apply() 好在哪?
省去上下文绑定(null)、不用记 API,还能混搭其他参数。
const nums = [4, 2, 7]; Math.max(...nums); // ✅ 7 Math.max(0, ...nums, 10); // ✅ 支持混合写法:0, 4, 2, 7, 10 → 10 // 替代写法(已过时): Math.max.apply(null, nums); // ❌ 冗长,且无法混搭
浅拷贝时,[...arr] 和 {...obj} 容易忽略什么?
它们只拷贝第一层,嵌套对象/数组仍共享引用——这不是 bug,是设计使然。
立即学习“Java免费学习笔记(深入)”;
const original = [{ a: 1 }, [2, 3]]; const copy = [...original]; copy[0].a = 99; console.log(original[0].a); // 99 ← 原数组被改了
- 需要深拷贝时,别硬套展开:用
structuredClone()(现代环境),或jsON.parse(json.stringify(obj))(简单场景) - 类数组对象(如
document.querySelectorAll('div'))必须先转为真数组才能用map/Filter:[...nodeList].map(...) - 空值防护建议:
{ ...(obj ?? {}) },避免obj为null时报错
展开运算符的威力不在“多厉害”,而在“恰到好处”——它解决的都是日常高频小痛点:拼数组、传参数、合并配置、解构剩余字段。但只要忘了它是浅拷贝,或对着 undefined 直接展开,错误就会立刻浮现。用之前,先问一句:我要展开的东西,真的可迭代吗?它的结构,我是否只动了第一层?