symbol() 创建的属性键具有唯一性与不可枚举性,能避免命名冲突;需用方括号或计算属性访问,不参与常规遍历;跨模块共享应使用 symbol.for();它不提供真正私有,仅作内部标记或扩展钩子。

用 Symbol() 创建属性键,就能确保它不跟任何字符串键或其他 Symbol 键重复——哪怕描述文字一模一样,每次调用也生成全新值。
基本创建与赋值方式
Symbol 是原始类型,不能用 new,直接调用函数即可:
-
const uid = Symbol('user id');—— 描述仅用于调试显示,不影响唯一性 -
obj[uid] = 123;—— 必须用方括号语法,点号写法无效 - 对象字面量中要用计算属性:
const user = { [uid]: 123 };
为什么能防冲突?关键在“不可枚举”和“不相等”
Symbol 属性天然隔离于常规遍历逻辑之外:
-
for...in、Object.keys()、JSON.stringify()都看不到它 -
Symbol('id') !== Symbol('id')—— 即使描述相同,也永远不相等 - 两个模块各自定义
Symbol('state'),不会互相覆盖
需要跨模块共享?用全局注册表 Symbol.for()
当多个文件或库需访问同一个 Symbol,就别用 Symbol(),改用:
-
const DEBUG = Symbol.for('debug');—— 全局池中查找,有则复用,无则新建 -
Symbol.keyFor(DEBUG)可反查出'debug'这个键名(仅对Symbol.for()创建的生效) -
Symbol('debug')和Symbol.for('debug')完全是两个东西
注意:不是私有,只是“不易被发现”
Symbol 属性仍可通过 Object.getOwnPropertySymbols() 拿到,所以它不提供真正封装:
- 适合做内部状态标记、插件扩展字段、行为定制钩子(如
Symbol.iterator) - 不适合替代
#私有字段或闭包来保护敏感数据 - 常见用途包括:自定义迭代器、类型判断(
Symbol.hasInstance)、替换魔术字符串
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











