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