Symbol是ES6新增的一种数据类型,用以标识独一无二的类型,所有的Symbol实例都是独一无二的
Symbol的使用方式
Symbol跟其他类不同,生成实例不需要使用 new 关键字,使用 new 关键字会报错,可以接受一个字符串作为Symbol的入参,也可以不传参直接生成,如下
let sm
= new Symbol()
let sm1
= Symbol()
console
.log(sm1
)
console
.log(typeof sm1
)
let sm2
= Symbol('test')
console
.log(sm2
)
每一个Symbol实例都不相同,如下实验
let sm
= Symbol()
let sm1
= Symbol()
console
.log(sm
=== sm1
)
let sm2
= Symbol('test')
let sm3
= Symbol('test')
console
.log(sm2
=== sm3
)
这也是Symbol最显著的特殊,可以让我们无后顾之忧的拓展对象属性,而不用担心会跟其现有的属性或方法冲突
Symbol.for()
如果都是使用上面的Symbol()来给对象赋值的的话我们就没法读取到该属性值了,如下
let a
= {}
a
[Symbol('test')] = 123
console
.log(a
[Symbol('test')])
因为在这里我们赋值跟取值的Symbol是完全不同的,为了避免这种情况,且能获取到对应的值我们需要使用Symbol.for()Symbol.for()方法的使用跟Symbol()的使用是一致的,可以接收一个字符串来做Symbol的唯一表示,调用该方式时,会从全局运行注册对象中查找有没有该Symbol,如果没有找到,就会生成一个Symbol对象并注册到全局运行注册对象中,然后返回该对象,如果查到了该Symbol,则直接返回该对象,所以看下示例:
let a
= Symbol
.for('test')
let b
= Symbol
.for('test')
console
.log(a
=== b
)
let c
= {}
c
[Symbol
.for('foo')] = 123
console
.log(c
[Symbol
.for('foo')])
使用Symbol()给对象赋值的方式,如下
let s1
= Symbol('foo'),
s2
= Symbol('bar'),
s3
= Symbol('baz'),
s4
= Symbol('qux')
let o
= {
[s1
]: 'foo val'
}
console
.log(o
)
Object
.defineProperty(o
, s2
, { value
: 'bar val' })
console
.log(o
)
Object
.defineProperties(o
, {
[s3
]: { value
: 'baz val' },
[s4
]: { value
: 'qux val' }
})
console
.log(o
)
Symbol.keyFor()
我们可以使用 Symbol.keyFor() 来检查一个Symbol实例是否存在与全局运行注册表中,该方法接收一个Symbol实例,如果全局注册表中存在该实例,则返回对应的key值,如果不存在,就会返回一个undefined,如下
Symbol
.keyFor(Symbol
.for('test'))
Symbol
.keyFor(Symbol('test'))
Object.getOwnPropertyNames() 跟 Object.getOwnPropertySymbols()
然后我们尝试使用 Object.getOwnPropertyNames 跟 Object.getOwnPropertySymbols 来获取一下对象o的值来看一下
Object
.getOwnPropertyNames(o
)
Object
.getOwnPropertySymbols(o
)
这里我们能看到使用 Object.getOwnPropertyNames 好像并不能获取到我们Symbol实例键,我们再给o拓展几个普通属性试试
o
['baz'] = '123'
o
['foo'] = '234'
Object
.getOwnPropertyNames(o
)
Object
.getOwnPropertySymbols(o
)
看到上结果我们也能知道,Object.getOwnPropertyNames 用于获取我们的常规除Symbol外的常规键值,Object.getOwnPropertySymbols 用于获取我们的Symbol键值
Object.getOwnPropertyDescriptors() 跟 Reflect.ownKeys()
然后我们再使用 Object.getOwnPropertyDescriptors() 跟 Reflect.ownKeys()来获取一下o的属性
Object
.getOwnPropertyDescriptors(o
)
Reflect
.keys(o
)
从中我们能看到 Object.getOwnPropertyDescriptors() 可以获取对象的常规值跟Symbol对应的值,Reflec.ownKeys() 可以获取对象的常规键跟Symbol键