概念

唯一标识符,属于基本类型,它不是字符串,不是数值,它就是个标志位,唯一。

创建

通过 Symbol() 创建即可,接收一个描述作为值 。如 Symbol('hell')

唯一性

即便描述一致,他们也是不同的标志符。

  1. Symbol('hello') === Symbol('hello') // false

如果想要访问到同一个Symbol? 看后面的全局symbol

不会自动转类型

  1. let id = Symbol('id')
  2. alert(id) // 报错,不会将Symbol value 转换为 string
  3. id + 1 // 报错,不会将Symbo value 转换为 number

可以用 toString() 看到一个显示的Symbol。也可以通过 .description 来访问创建时的描述。如:

  1. let id = Symbol('hello')
  2. id.description // hello

用它写“隐藏”属性

之所以隐藏打引号,说明并不是真正的隐藏
常用的方法如 for in Object.keys 都没法获取到使用 Symbol 的作为对象键名的值。
但是ES6新增的 Reflect 提供的 ownKeys 方法可以获取到所有的key值,也可以使用 Object.getOwnPropertySymbols(obj) 获取到所有的 Symbol

可以借助这个特性,对一些第三方库的代码中的对象做扩展,还不太会影响。毕竟大部分的库还是没有使用Reflect方法。

另外,拷贝对象是可以拷贝到 Symbol 为键名的属性的。如

  1. let id = Symbol('id')
  2. let a = {[id]: 'hello'}
  3. let b = Object.assign({}, a) // {Symbol(id): "hello"}

全局symbol

正如上面提到的,即便描述一致,也不是同一个 symbol ,如果需要访问同一个Symbol,可以使用 全局Symbol注册表。
这里使用 Symbol.for 查询或创建指定描述的 Symbol

  1. let id = Symbol.for('id')
  2. let searchId = Symbol.for('id')
  3. searchId === id // true

另外还能通过 Symbol.keyFor 反向查找描述符

  1. let id = Symbol.for('yes!')
  2. Symbol.keyFor(id) // yes!

系统Symbol

JS内部的系统级 Symbol 。后面学习到再补。