Symbol
是 ES6 (时隔多年) 新增的一种 primitive type ,可以把它看做一种自动生成 唯一值 的机制,它的真实值在代码中无法直接获得。
主要用来作为对象的 Key 避免命名冲突。
// 最基础的方式
const a = Symbol()
// 可以传入一串描述该 Symbol 用途的字符串作为参数
const b = Symbol('some description text')
// 从全局的 Symbol 库中查询所需的结果
// 如果未找到则新建一个并返回
// 这种方式较以上直接构造 Symbol 的优点在于
// 可以不必在外部作用域中专门维护一个变量用于存储生成的 Symbol
const c = Symbol.for('my Symbol')
// 由于 Symbol 全局存在
// 为了尽量避免命名冲突 可以在描述中添加前缀
const d = Symbol.for('prefix.Symbol')
// 注意 new Symbol() 会报错 Uncaught TypeError: Symbol is not a constructor
const sym = Symbol()
// 推荐方式
typeof sym === 'symbol'// true
// 并不是一种类与实例化对象的关系 无法通过以下方法判断
sym instanceof Symbol // false
const a = Symbol('desc a')
const b = Symbol.for('desc b')
a.description // desc a
b.description // desc b
Symbol.keyFor(a) // undefined
Symbol.keyFor(b) // desc b
a.toString() // Symbol(desc a)
b.toString() // Symbol(desc b)
通过上述对比,个人感觉用 Symbol.for()
来生成 Symbol
好像更加合适,不仅可以少声明一个变量,并且能更方便的获得其描述。
Symbol.for()
会从某种程度上破坏 Symbol
的唯一特性,所以上述俩种生成 Symbol
的方式应该各有适用的场景。
借助 Symbol
来实现单例模式
function singleton() {
const Instance = Symbol.for('instance')
if (singleton[Instance]) {
return singleton[Instance]
}
return singleton[Instance] = {}
}
const a = singleton()
const b = singleton()
a === b // true
Symbol
作为对象的 Key 时不会被当作普通的键值被遍历。
但还是可以通过 Object.getOwnPropertySymbols()
来获得,所以严格来说 Symbol 并不能完全实现私有属性的需求。
// 这里要注意 const o = { Symbol(): 2 } 这种写法会报错
const o = {
foo: 1,
[Symbol.for('bar')]: 2
}
Object.getOwnPropertyNames(o) // ['foo']
Object.getOwnPropertySymbols(o) // [Symbol(for)]
Object.keys(o) // ['foo']
for (let key in o ){
console.log(key) // 'foo'
}
个人认为 ES6 自带的 Built-in Symbols(aka. Well-known Symbols) 才是最常见的用法。
从这点来看 Symbol
对于语言内部实现来说确实有帮助,当协议制定者向原型链上新增属性或方法时就不用再担心与开发者产生命名冲突了,例如 Symbol.iterator
:
const arr = [1, 2, 3]
arr[Symbol.iterator] // native function
const it = arr[Symbol.iterator]() // 获得数组的 Iterator
以及 Symbol.toStringTag
:
const test = {
[Symbol.toStringTag]: 'TestClass'
}
Object.prototype.toString.call(test) // "[object TestClass]"
值得一提的是这些内部的 Symbol
并没有注册到全局库中,而是作为 Symbol
的静态属性存在。
想要更深入的了解推荐看一下 ES6 In Depth: Symbols。
完。