「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」。
基本概念
- ES6中引入了一种新的原始数据类型
symbol - 在MDN中这样描述
symbol 是一种基本数据类型 (primitive data type)。
Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的symbol注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()"。
每个从
Symbol()返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据类型仅有的目的。
基本使用
let apple = Symbol()
let banana = Symbol()
typeof apple // 'symbol'
apple == banana // false
apple === banana // false
- 任意两个
symbol都不相等
Symbol.for(key)
使用给定的key搜索现有的symbol,如果找到则返回该symbol。否则将使用给定的key在全局symbol注册表中创建一个新的symbol。
let uid1 = Symbol.for('uid')
let uid2 = Symbol.for('uid')
uid1 // 'Symbol(uid)'
uid2 // 'Symbol(uid)'
uid1 === uid2 // true
Symbol.keyFor(sym)
从全局symbol注册表中,为给定的symbol检索一个共享的symbol key。
let uid = Symbol.for('uid')
Symbol.keyFor(uid) // 'uid'
使用场景
定义私有变量
- 用
symbol可以很方便的模仿私有属性,Object.keys()不会拿到用symbol类型的属性,除非使用Object.getOwnPropertySymbols(),并且只有用这个symbol的引用才能访问该属性的值
let obj = {
public: 'i am public'
}
const private = Symbol('private')
obj[private] = 'i am private'
Object.keys(obj) // ['public']
Object.getOwnPropertySymbols(obj) // [Symbol(private)]
obj[Symbol('private')] // undefined
obj[private] // 'i am private'
消除魔术字符串
- 实际开发中,随着业务逐渐复杂,可能会产生与业务无关的且重复的魔法字符,这不利于日后业务的修改和维护
function doSomething(type) {
switch(type) {
case 'type1':
'do case1'
break
case 'type2':
'do case2'
break
case 'type3':
'do case3'
break
default:
'do default'
break
}
}
doSomething('type1')
- 由于任意两个用
Symbol()定义的变量都是不相等的,因此可以不用关心字符串本身
let obj = {
type1: Symbol(),
type2: Symbol(),
type3: Symbol(),
}
function doSomething(type) {
switch(type) {
case obj.type1:
'do case1'
break
case obj.type2:
'do case2'
break
case obj.type3:
'do case3'
break
default:
'do default'
break
}
}
doSomething(obj.type1)