深拷贝需显式处理symbol属性:用object.getownpropertysymbols()获取,配合getownpropertydescriptor()保留属性特性,递归拷贝值但直接复用symbol实例。

JavaScript 中手动实现深拷贝时,Symbol 属性默认不会被常规遍历方法(如 for...in、Object.keys()、JSON.stringify())捕获,因此必须显式处理才能保留。
Symbol 属性需通过 Object.getOwnPropertySymbols() 获取
与字符串键不同,Symbol 作为对象属性名是不可枚举的,也不会出现在 Object.keys() 或 for...in 循环中。要访问它们,必须使用 Object.getOwnPropertySymbols(),它返回对象自身所有 Symbol 类型的键(不含继承的)。
- 配合
Object.getOwnPropertyDescriptors()可同时获取 Symbol 属性的描述符(包括value、enumerable、writable等),便于准确复制属性特性 - 注意:若原对象的 Symbol 属性是通过
Object.defineProperty设置为不可枚举或不可配置,深拷贝时也应复现这些特性,否则可能破坏行为一致性
深拷贝中需递归处理 Symbol 属性的值
获取到 Symbol 键后,不能简单地用 target[symbol] = source[symbol] 赋值——这仅适用于基本类型或浅层引用。若 Symbol 对应的值本身是对象(如另一个对象、数组、甚至嵌套 Symbol 值),必须递归调用深拷贝函数处理。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 例如:
obj[Symbol('meta')] = { id: 1, tags: ['a', 'b'] },其中tags数组需要被深拷贝,而非共享引用 - 建议在主拷贝逻辑中统一处理所有自有属性(字符串键 + Symbol 键),避免逻辑割裂
注意全局 Symbol 和 Symbol.for() 的特殊性
Symbol 值本身是唯一且私有的,但通过 Symbol.for(key) 创建的是全局注册的 Symbol。深拷贝时,Symbol 实例不会被“复制”,而是应直接复用原 Symbol——因为 Symbol 没有“深浅”之分,它本身就是原始值;拷贝后仍需指向同一个 Symbol 实例,才能保持语义一致(比如用于全局唯一标识或私有字段)。
-
typeof Symbol('a')是'symbol',属于原始类型,直接赋值即可(如target[sym] = source[sym]) - 不要尝试对 Symbol 调用递归深拷贝,也不应把它转成字符串再还原(会丢失唯一性)
示例:支持 Symbol 的简易深拷贝片段
以下逻辑可嵌入已有深拷贝函数中:
// 假设 target 和 source 已确定为普通对象,且 target 已初始化为空对象
const symbols = Object.getOwnPropertySymbols(source);
for (const sym of symbols) {
const descriptor = Object.getOwnPropertyDescriptor(source, sym);
// 递归拷贝 value(若为对象/数组等),其他 descriptor 字段(如 writable)直接保留
const value = isPlainObject(descriptor.value) || Array.isArray(descriptor.value)
? deepClone(descriptor.value)
: descriptor.value;
Object.defineProperty(target, sym, {
...descriptor,
value
});
}
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










