ES6 新增數(shù)據(jù)結(jié)構(gòu)之 Symbol
Symbol
?ES5 中的對(duì)象屬性名都是字符串,這容易造成屬性名的沖突。比如,當(dāng)你想要為一個(gè)已有的對(duì)象添加一個(gè)新屬性,而新屬性的名字很有可能與現(xiàn)在已有的屬性沖突。
為了解決這一問題,ES6 引入了一種新的原始數(shù)據(jù)類型Symbol,它表示獨(dú)一無二的值。
1. Symbol值 通過 Symbol()生成。
創(chuàng)建一個(gè) Symbol的實(shí)例 :
let? s = Symbol()
typeof? s? //? symbol
2. Symbol ( ) 也可以接受一個(gè)字符串作為參數(shù),僅表示對(duì)生成的symbol值的描述,目的是讓人更容易區(qū)分。
let s =? Symbol('first');
let ss =? Symbol('last');
s?? // Symbol(first)
ss? // Symbol(last)
3. Symbol ( ) 的參數(shù)只是對(duì)當(dāng)前 Symbol值的描述,相同參數(shù)的 Symbol值 是不相等的。
let s1 =? Symbol();
let s2 =? Symbol();
s1 === s2 // false
let s =? Symbol('first');
let ss =? Symbol('first');
s === ss? // false
4. Symbol ( )? 前不能使用 new ,否則會(huì)報(bào)錯(cuò)。 記住,新生成的 Symbol值 是一個(gè)原始數(shù)據(jù)類型值,不是對(duì)象。
5. Symbol 值不能與其他類型的值進(jìn)行運(yùn)算。
6. Symbol 值可以轉(zhuǎn)換為字符串、布爾值。
let? s =? Symbol('first');
// 可以轉(zhuǎn)換為字符串
s.toString()? // 'Symbol('first')'
String(s)? // 'Symbol('first')'
// 可以轉(zhuǎn)換為布爾值
Boolean(s)? // true
!s // false
if (s) { console.warn( 'true') }
7. 每一個(gè)Symbol值都是獨(dú)一無二,不相等的。 正由于這種特性 Symbol數(shù)據(jù)類型的主要用途是作為對(duì)象屬性名。
let?mySymbol?=?Symbol();
var?a?=?{};
a[mySymbol]?=?'Hello!';
console.log(a[mySymbol]);? // Hello!
var?a?=?{
????[mySymbol]?:?'World!'
}
console.log(a[mySymbol]);? // World!
var?a?=?{};
Object.defineProperty(a,?mySymbol,?{?value:?'Hello?World!'})
console.log(a[mySymbol]);? // Hello World!
8. Symbol 值作為對(duì)象屬性名不能使用 點(diǎn)運(yùn)算符。
let?mySymbol?=?Symbol();
var?a?=?{};
a.mySymbol = 'Hello!';
console.log ( a[mySymbol] );? // undefined
console.log ( a['mySymbol'] )? // Hello!
console.log(?a.mySymbol);? // Hello!
我們平時(shí)調(diào)用一個(gè)對(duì)象屬性或方法,是點(diǎn)運(yùn)算符后接屬性名,即 obj.property。也就是說,上面代碼其實(shí)是將 ‘mySymbol’ 這個(gè)字符串作為屬性名存 入了 a 對(duì)象。
即: a { 'mySymbol' : 'Hello!' }
所以即使是在對(duì)象內(nèi)部,我們定義Symbol值的屬性名時(shí),也要寫在方括號(hào)內(nèi)。
即正確寫法應(yīng)是:a{ [mySymbol] : 'Hello!' }
9. 重難點(diǎn):
?Symbol 作為屬性名,該屬性不會(huì)出現(xiàn)在for...in
、for...of
循環(huán)中,也不會(huì)被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回。但是,它也不是私有屬性,有一個(gè)Object.getOwnPropertySymbols
(),可以獲取指定對(duì)象的所有 Symbol 屬性名。Reflect.ownKeys
() 可以返回所有類型的鍵名,包括常規(guī)鍵名和 Symbol 鍵名。
10.Symbol.for(), Symbol.keyFor()
Symbol.for() 接受一個(gè)字符串作為參數(shù),然后先搜索有沒有以該參數(shù)作為名稱的Symbol值。如果有,就返回這個(gè)Symbol值,沒有就新建并返回一個(gè)以該字符串為名稱的Symbol值。注意,symbol() 返回的值不會(huì)在全局環(huán)境中登記,一旦創(chuàng)建,就是獨(dú)一無二的值。
var s = Symbol('123')
var s1 = Symbol.for('123');
var s2 = Symbol.for('123');
s === s1 // false?
s1 === s2 // true
Symbol.keyFor()返回一個(gè)已登記的 Symbol 類型值的 key。