symbol()每次调用都生成全新唯一值,即使描述相同也不相等;参数仅用于调试,不影响唯一性;用作对象键时需方括号语法,不可枚举且避免命名冲突。

直接用 Symbol() 函数调用就能创建独一无二的属性名,它不依赖参数内容,每次调用都生成全新值——哪怕描述文字完全一样,两个 Symbol 也永远不相等。
基础创建与赋值方式
Symbol 是原始类型,不能加 new;参数仅作调试标识,不影响唯一性:
-
const id = Symbol('user id');—— 创建一个带描述的 Symbol -
const obj = { [id]: 'abc' };—— 对象字面量中必须用计算属性语法(方括号) -
obj[id] = 'xyz';—— 给对象添加 Symbol 属性,点号写法无效(obj.id拿不到)
为什么能真正避免命名冲突
关键在两点:不可枚举 + 不可复用:
-
Symbol('state') !== Symbol('state')—— 描述相同也不相等,各模块独立创建互不影响 - 不会出现在
for...in、Object.keys()、JSON.stringify()中,天然隔离于常规遍历逻辑 - 即使多个库都写了
Symbol('debug'),彼此属性也不会覆盖或误读
跨文件/模块共享同一个 Symbol
如果不同模块需要访问“同一个” Symbol(比如统一开关、调试标记),就得用全局注册表:
-
const DEBUG = Symbol.for('debug');—— 全局池中查找,有则复用,无则新建 -
Symbol.keyFor(DEBUG)可反查出字符串键名'debug'(仅对Symbol.for()创建的有效) -
Symbol('debug') !== Symbol.for('debug')—— 它们是完全不同的两个值
读取和检测 Symbol 属性
它不是私有,只是“默认隐身”,仍可通过特定 API 访问:
-
Object.getOwnPropertySymbols(obj)—— 获取对象所有 Symbol 类型的自有属性 -
Reflect.ownKeys(obj)—— 返回包括字符串和 Symbol 的全部键名 -
obj[Symbol.iterator]这类内置 Symbol 可用于自定义行为(如迭代、类型判断)











