Symbol
ES6 新增的原始类型,用来提供唯一标识、避免属性冲突和承载内置协议扩展点。
#type / concept
#status / growing
#resource / javascript
#resource / ecmascript
[!info] related notes
- 所属 MOC: ES6 新特性 MOC, ECMAScript MOC
- 前置概念: ECMAScript类型判断
- 并列概念: ECMAScript集合引用类型, ECMAScript代理与反射
- 相关协议: ECMAScript迭代器和生成器, Iterable, Iterator, Generator, Iterable、Iterator、Generator 关系
Symbol
一句话定义
Symbol 是 ES6 新增的原始类型,每个 Symbol 都是唯一的,常用于对象属性的唯一键和语言内置协议扩展点。
核心内容
唯一性
const a = Symbol('id')
const b = Symbol('id')
a === b // false
即使描述相同,Symbol() 也不会复用值。
作为属性键
const key = Symbol('secret')
const obj = { [key]: 123 }
Symbol 键不会和普通字符串属性冲突。
它很适合做库、框架、插件里的内部标记。
全局注册表
const a = Symbol.for('cache')
const b = Symbol.for('cache')
a === b // true
Symbol.for() 会走全局注册表,适合需要跨模块复用同一个标记的场景。
遍历与序列化
const s = Symbol('secret')
const obj = { a: 1, [s]: 2 }
Object.keys(obj) // ['a']
Object.getOwnPropertySymbols(obj) // [Symbol(secret)]
Reflect.ownKeys(obj) // ['a', Symbol(secret)]
JSON.stringify(obj) // {"a":1}
Symbol 键默认不会出现在常规枚举和 JSON 序列化里,但仍然可以通过反射 API 取到。
常见内置 Symbol
Symbol.iteratorSymbol.toStringTagSymbol.hasInstanceSymbol.toPrimitive
这些 Symbol 是 JavaScript 语言层面的协议入口。
常见用途
- 防止对象属性冲突
- 给对象挂内部标记
- 接入
for...of、类型转换、instanceof等语言协议
边界与易混淆点
Symbol()每次都会新建唯一值Symbol.for()走全局注册表- Symbol 不是字符串,序列化和遍历行为都和普通属性不同
- Symbol 不是“真正私有”,只能算默认不暴露
最短记忆方式
- 唯一
- 作为键
- 用来定义语言协议