#背景
ES5中,属性都可以通过点方法来获取和赋值。这也带来了一个问题,当我想给一个类增加属性的时候,除非我看完这个类的所有细节,否则我很难知道一个属性名是否已经被占用。而ES6为了解决这个问题,引入了一个新的原始类型Symbol,它表示独一无二的值,来避免重复的命名。
加入Symbol之后,JS中的基础类型共有:
- undefined
- Null
- Boolean
- String
- Number
- Object
- Symbol
#使用
初始化
Symbol的初始化方法很简单,但是要注意,它不是对象(Object),所以不能用new初始化
|
|
Symbol没有属性,是一个类似于string的数据类型,我的理解,Symbol其实就是独一无二的string。
|
|
Symbol可以通过加参数的形式来区分不同的Symbol,如下:
|
|
注意,即使使用相同的参数来初始化,得到的实例也是不同的,比如:
|
|
如果想要获取以某个string为参数的Symbol,在之后会讲到Symbol.for()函数。
赋值
使用Symbol给属性赋值,用法和string属性赋值基本相似,但是不可以用.
,要用[]
。以下是三种赋值方法:
|
|
使用场景
Symbol的一个场景是上述提到的,给一个类增加属性,而避免属性重复。
第二是使用在常量中,switch case
来保证唯一性。
|
|
注意事项(和string属性不同的地方)
最主要的区别,使用 for ... in
、 for ... of
或者Object.keys()
、 Object.getOwnPropertyNames()
不会返回Symbol
如果想获取对象的所有Symbols,使用函数getOwnPropertySymbols
有个新的API,Reflect.ownKyes
,会返回所有的String属性和Symbol属性
Symbol.keyFor和Symbol.for
Symbol.for
Symbol会返回一个新的实例,无论参数是什么,上面已经将到了。
|
|
而Symbol.for则会先搜索是否有以这个参数初始化的Symbol,如果有则放回这个Symbol,否则初始化一个新的,实现逻辑如下
|
|
和第一个例子对比看下:
|
|
如果Symbol和Symbol.for混用呢?
|
|
这说明两者是没有打通的,即Symbol初始化的实例无法被Symbol.for找到
Symbol.keyFor
用Symbol.for来初始化的Symbol,如何知道它的初始化参数呢,这里提供了一个方法: Symbol.keyFor
|
|
注意,Symbol初始化不能用这个函数
|
|
注意:Symbol.for 为Symbol值登记的是全局的,这意味着在不同的iframe都可以取到同一个值。