JavaScript深拷贝需用Object.getOwnPropertySymbols()显式提取Symbol键,因其不可被for...in或Object.keys()遍历,再递归拷贝值并赋给目标对象,Symbol本身无需新建。

JavaScript 深拷贝要正确保留 Symbol 类型的键名,核心在于:Symbol 属性不可被常规遍历方法捕获,必须显式提取并单独处理。
Symbol 键不会出现在 for...in 或 Object.keys() 中
Symbol 作为对象属性名时默认不可枚举,即使设置 enumerable: true,for...in、Object.keys()、JSON.stringify() 仍会跳过它。例如:
const obj = { a: 1 };
const sym = Symbol('id');
obj[sym] = 'abc';
console.log(Object.keys(obj)); // ['a']
console.log(JSON.stringify(obj)); // {"a":1}
必须用 Object.getOwnPropertySymbols() 提取
这是唯一可靠获取对象自有 Symbol 键的方式,返回一个 Symbol 数组:
- Object.getOwnPropertySymbols(obj) 获取所有自有 Symbol 属性
- 配合 Object.getOwnPropertyDescriptors(obj) 可同时读取属性描述符(如 writable、configurable)
- 再用 Object.defineProperty(target, sym, descriptor) 或直接赋值写入新对象
在递归深拷贝中加入 Symbol 分支
手写深拷贝函数时,在处理普通对象逻辑后补充 Symbol 支持:
立即学习“Java免费学习笔记(深入)”;
- 调用 Object.getOwnPropertySymbols(source) 获取 Symbol 键列表
- 遍历每个 Symbol 键,对 source[sym] 的值做深拷贝(引用类型递归,基本类型直传)
- 将结果赋给目标对象:target[sym] = clonedValue
注意:Symbol 值本身是原始类型,拷贝时复用原 Symbol 即可,无需“新建”Symbol —— 它天然唯一且不可变。


















