Symbol 是 JavaScript 中用于创建唯一、不可枚举属性键的原始类型,可避免命名冲突;支持局部唯一性、全局注册表(Symbol.for)、内置行为定制(如 Symbol.iterator),但非真正私有。

Symbol 是 JavaScript 中一种原始数据类型,专门用于创建唯一、不可枚举的属性键,能有效避免属性名冲突,特别适合定义对象私有或内部标识。
Symbol 的基本用法
调用 Symbol() 函数会返回一个唯一的 Symbol 值,即使描述相同,每次调用也生成不同值:
-
Symbol('id') !== Symbol('id')—— 两个 Symbol 永远不相等 - Symbol 值不能与其他类型隐式转换(如拼接字符串会报错),需显式调用
.toString()或String(sym) - Symbol 属性不会被
for...in、Object.keys()、JSON.stringify()遍历或序列化,属于“隐形”属性
作为对象属性键使用
Symbol 可直接用作对象属性名,确保该属性不会被意外覆盖或遍历到:
- 用方括号语法赋值:
obj[Symbol('name')] = 'Alice'; - 可在对象字面量中使用计算属性:
const sym = Symbol('uid'); const user = { [sym]: 123 }; - 获取时同样需用 Symbol 变量:
user[sym],不能用字符串'uid'
全局 Symbol 注册表:Symbol.for() 和 Symbol.keyFor()
若需要跨模块共享同一个 Symbol,可用全局注册表:
立即学习“Java免费学习笔记(深入)”;
-
Symbol.for('debug')会先检查全局池,存在则复用,否则新建并登记 -
Symbol.keyFor(sym)可反查该 Symbol 对应的注册键名(仅对Symbol.for()创建的生效) - 注意:
Symbol('debug')和Symbol.for('debug')完全不同,前者始终唯一,后者可共享
内置 Symbol 与行为定制
JavaScript 预定义了一批以 Symbol 开头的全局常量(如 Symbol.iterator),用于自定义对象行为:
- 让对象支持
for...of:定义[Symbol.iterator]()方法返回迭代器 - 自定义
console.log(obj)输出:实现[Symbol.toStringTag]返回字符串标签 - 控制 JSON 序列化逻辑:设置
[Symbol.toJSON]()方法
Symbol 不是“私有变量”的替代品(仍可通过 Object.getOwnPropertySymbols() 获取),但它提供了可靠的命名隔离机制,在库开发、状态管理或元编程中非常实用。


















