ES6 Symbol 用法
[ES6] Symbol 用法
Symbol 是什么?
Symbol 是 ES6 新增的一个数据类型,也是 JS 原生数据类型(Number,String,Boolean,undefined,null,Object,Bigint,Symbol)之一,表示独一无二的值。
为什么要有 Symbol ?
防止对象的属性名冲突
以往对象的属性名都是字符串,在使用的过程中,可能会出现属性名重复导致冲突的情况,于是 ES6 引入了Symbol,表示独一无二的值,避免了属性名的重复。
用法
创建一个 Symbol
| 1 |  | 
可以看到,这里是调用了 Symbol() 函数创建了一个 Symbol ,不需要使用 new 操作符,注意区分。
Symbol() 可以接受一个字符串作为参数,表示对这个 Symbol 的描述:
| 1 |  | 
如果该参数为对象,则调用对象的toString()方法转为字符串。
这个参数只作为描述存在,相同描述的Symbol并不相等。
| 1 |  | 
Symbol.prototype.description
可以通过这个方法,获取创建 Symbol 时的描述字符串:
| 1 |  | 
作为属性名
| 1 |  | 
三种方式都可以。注意在使用 Symbol 作为属性名时,不能使用.操作符,例如a.s1这里的s1实际上是字符串s1,和我们定义的 Symbol 没关系。
在对象内部使用时,也需要用[]包裹,不然也会被当做字符串处理。
属性名的遍历
Symbol 作为属性名时,是公有属性而不是私有属性,但是不能通过常规方式遍历到,例如:
- 
for...in
- 
for...of
- 
Object.keys()
- 
Object.getOwnPropertyNames()
- 
JSON.stringify()
可以通过以下方式获取到:
- 
Object.getOwnPropertySymbols()返回当前对象中所有用作属性名的 Symbol 值的数组
- 
Reflect.ownKeys()返回所有类型的键名,包括常规键名和 Symbol 键名
Symbol.for()
Symbol.for()接受一个字符串,然后会查找有没有使用这个字符串作为名称的 Symbol 值,如有有,就返回这个 Symbol 值,如果没有,则会以该字符串创建一个新的 Symbol 并注册到全局。并且,不论Symbol.for()在何处运行,注册的名字永远在全局环境中。
| 1 |  | 
Symbol.keyFor()
Symbol.keyFor()接受一个 Symbol 参数,并返回这个 Symbol 注册时的 key,往往和 Symbol.for() 配合使用,因为通过 Symbol() 创建的 Symbol 并没有注册 key,只用通过 Symbol.for() 注册的 Symbol 才是有 key 的。
| 1 |  | 
上述代码中,s2并没有注册 key。
内置 Symbol 值
- 
Symbol.hasInstance 
- 
Symbol.isConcatSpreadable 
- 
Symbol.species 
- 
Symbol.match 
- 
Symbol.replace 
- 
Symbol.search 
- 
Symbol.split 
- 
Symbol.iterator 对象的 Symbol.iterator属性,指向该对象的默认遍历器方法。
- 
Symbol.toPrimitive 
- 
Symbol.toStringTag 
- 
Symbol.unscopables