javascript中浅拷贝通过扩展运算符(...)复制数组、类数组对象、set、map和普通对象,但需注意类型适配:数组直接展开;类数组需array.from或解构;set/map须先转数组再重建;对象仅拷贝可枚举自有属性。

JavaScript 中浅拷贝通过扩展运算符(...)复制集合,本质是将集合的可枚举、自身、非 Symbol 键的属性或元素逐个展开到新结构中。它适用于数组、类数组对象(需先转换)、以及普通对象,但不适用于 Set、Map 等原生集合类型——因为它们没有默认的可枚举属性遍历接口,直接用 {...set} 或 [...map] 会报错或得到意外结果。
下面分场景说明怎么正确使用扩展运算符处理常见集合类型:
数组:直接展开即可
数组是可迭代对象,支持 ... 语法,是最典型的适用场景:
const arr = [1, 2, { name: 'Alice' }];
const copy = [...arr];
copy[0] = 99;
copy[2].name = 'Bob';
console.log(arr[0]); // 1 → 基本类型未受影响
console.log(arr[2].name); // 'Bob' → 引用类型仍共享
✅ 有效、简洁、推荐用于一维或确定无深层嵌套的数组。
类数组对象(如 arguments、NodeList):需先转为数组
它们不可直接用 [...args](旧环境可能报错),应配合 Array.from() 或解构:
function fn() {
const args = [...arguments]; // ✅ ES2015+ 多数环境支持
// 或 const args = Array.from(arguments);
}
⚠️ 注意:arguments 是类数组,不是真正数组,但现代 JS 中 ... 在函数参数位置已原生支持,无需额外转换。
Set:必须显式转为数组再展开
Set 本身是可迭代的,所以可以用 [...set] 得到数组副本;但不能用 {...set}(会报错,因 Set 没有键值对结构):
const set = new Set([1, 2, 3]); const arrCopy = [...set]; // [1, 2, 3] —— 浅拷贝数组 const setCopy = new Set(arrCopy); // 再包回 Set,完成“集合浅拷贝”
❌ 错误写法:{...set} → TypeError: Found non-callable @@iterator
Map:同理,需先展开为数组,再重建
Map 迭代返回 [key, value] 对,可用扩展运算符转为二维数组,再传给 new Map():
const map = new Map([['a', 1], ['b', { x: 10 }]]);
const mapCopy = new Map([...map]); // ✅ 浅拷贝 Map
mapCopy.get('b').x = 99;
console.log(map.get('b').x); // 99 → 嵌套对象仍共享引用
对象:只拷贝可枚举自有属性,不处理原型、Symbol、getter
const obj = { a: 1, b: [2, 3] };
const copy = { ...obj }; // ✅ 浅拷贝第一层
// ❌ 不会拷贝:
// Object.defineProperty(obj, 'hidden', { value: 4, enumerable: false });
// obj[Symbol('id')] = 'abc';
// Object.defineProperty(obj, 'computed', { get() { return Date.now(); } });
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











