symbol是es6中独一无二的原始类型,用作对象私有属性键可避免命名冲突;需方括号访问、不可枚举、不参与json序列化;symbol.for()支持全局共享,symbol.keyfor()可反查键名。

ES6 中的 Symbol 是一种原始数据类型,每次调用 Symbol() 都会返回一个**独一无二、不可复用**的值,因此非常适合用作对象的私有或唯一属性键,避免命名冲突和意外覆盖。
用 Symbol 作为对象属性名
Symbol 值不能被自动转换为字符串(隐式转换会报错),必须显式调用 .toString() 或使用 String(sym) 才能转成字符串。把它当作属性名时,需用方括号语法([]),不能用点号(.)。
-
const myKey = Symbol('description');—— 创建带描述符的 Symbol(描述仅用于调试,不影响唯一性) -
obj[myKey] = 'value';—— 正确:用中括号赋值/读取 -
obj.myKey或obj.myKey—— 错误:点号访问不到 Symbol 属性
Symbol 属性不会被常规遍历枚举
Symbol 类型的属性名默认是“不可枚举”的,所以 for...in、Object.keys()、JSON.stringify() 都不会包含它,但可通过 Object.getOwnPropertySymbols() 获取。
-
Object.keys(obj)→ 返回所有字符串键,不含 Symbol 键 -
Object.getOwnPropertyNames(obj)→ 同样只返回字符串键 -
Object.getOwnPropertySymbols(obj)→ 专门获取 Symbol 类型的自有属性名 -
Reflect.ownKeys(obj)→ 同时返回字符串键 + Symbol 键(推荐用于完整遍历)
全局 Symbol 注册表:Symbol.for() 和 Symbol.keyFor()
如果需要跨模块共享同一个 Symbol(比如统一标识某个功能),可用 Symbol.for(key)。它会先检查全局注册表中是否存在该 key,存在则复用,否则新建并登记。
-
const sym1 = Symbol.for('shared'); const sym2 = Symbol.for('shared');→sym1 === sym2为 true -
Symbol.keyFor(sym1)→ 返回'shared'(仅对Symbol.for()创建的 Symbol 有效) - 普通
Symbol('shared')每次都不同,且不进入全局注册表
实际防覆盖场景示例
比如在工具函数中给对象添加临时标记,又不想干扰用户原有属性:
const processed = Symbol('processed');function cacheResult(obj, result) { obj[processed] = true; obj.cached = result; }- 即使对象原本有
processed字符串属性,也不会被覆盖;其他代码也几乎不可能意外创建同名 Symbol
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











