普通符號
符號是ES6新增的一個數(shù)據(jù)類型,它通過函數(shù)Symbol(符號名)
來創(chuàng)建
符號設(shè)計的初衷综芥,是為了給對象設(shè)置私有屬性
私有屬性猎拨,只能在對象內(nèi)部使用,外面無法使用
符號具有以下特點:
- 沒有字面量
- 使用
typeof
得到的類型是Symbol
- 每次調(diào)用
Symbol
函數(shù)得到的符號永遠(yuǎn)不相等额各,無論符號名是否相同 - 符號可以作為對象的屬性名存在吧恃,這種屬性稱之為符號屬性
- 開發(fā)者可以通過精心的設(shè)計痕寓,讓這些屬性無法通過常規(guī)方式被外界訪問
- 符號屬性是不能枚舉的,因此在
for-in
循環(huán)中無法讀取到符號的屬性呻率,Object.keys
方法也無法讀取到符號屬性 - ```Object.getOwnPropertyNames``盡管可以得到所有無法枚舉的屬性,但是仍然無法讀取到符號屬性
- ES6新增
Object.getOwnPropertySymbols
方法礼仗,可以讀取符號
- 符號無法被隱式轉(zhuǎn)換吐咳,因此不能被用于數(shù)學(xué)運算、字符串拼接或其他隱式轉(zhuǎn)換場景元践,但符號可以以顯示轉(zhuǎn)換為字符串韭脊,通過
String
構(gòu)造函數(shù)進(jìn)行轉(zhuǎn)換即可,console.log
之所以可以輸出符號单旁,是它在內(nèi)部進(jìn)行了顯示轉(zhuǎn)換
共享符號
根據(jù)某個符號名稱(符號描述)能夠得到同一個符號
Symbol.for("符號描述/名稱") // 獲取共享符號
const syb1 = Symbol.for("abc")
const syb2 = Symbol.for("abc")
console.log(syb1 === syb2) // true
const obj1 = {
a: 1,
b: 2,
[syb1]: 3
}
const obj2 = {
a: 1,
b: 2,
[syb2]: 3
}
console.log(obj1, obj2)
知名符號
知名符號是一些具有特殊含義的共享符號沪羔,通過Symbol的靜態(tài)屬性得到ES6延續(xù)了ES5的思想:減少魔法,暴露內(nèi)部實現(xiàn)
因此慎恒,ES6用知名符號暴露了某些場景的內(nèi)部實現(xiàn)
- Symbol.hasInstance
該符號用于定義構(gòu)造函數(shù)的靜態(tài)成員任内,它將影響instanceof的判定
obj instanceof A
//等用于
A[Symbol.hasInstance](obj)
Symbol.inConcatSpreadable
該知名符號會影響數(shù)組的concat方法Symbol.toPrimitive
該知名符號會影響類型轉(zhuǎn)換的結(jié)果Symbol.toStringTag
該知名符號會影響 Object.prototype.toString的返回值其他知名符號