一、Symbol
ES6 引入了一種新的原始數據類型Symbol
,表示獨一無二的值。它是 JavaScript 語言的第七種數據類型,前六種是:undefined
、null
、布爾值(Boolean)、字符串(String)、數值(Number)、對象(Object)。
注意,Symbol
函數前不能使用new
命令,否則會報錯。這是因爲生成的 Symbol 是一個原始類型的值,不是對象。也就是說,由於 Symbol 值不是對象,所以不能添加屬性。基本上,它是一種類似於字符串的數據類型。
let s1 = Symbol('foo');
let s2 = Symbol('bar');
s1 // Symbol(foo)
s2 // Symbol(bar)
s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"
注意,Symbol
函數的參數只是表示對當前 Symbol 值的描述,因此相同參數的Symbol
函數的返回值是不相等的。
// 沒有參數的情況
let s1 = Symbol();
let s2 = Symbol();
s1 === s2 // false
// 有參數的情況
let s1 = Symbol('foo');
let s2 = Symbol('foo');
s1 === s2 // false
2.作爲屬性名的Symbol
由於每一個 Symbol 值都是不相等的,這意味着 Symbol 值可以作爲標識符,用於對象的屬性名,就能保證不會出現同名的屬性。這對於一個對象由多個模塊構成的情況非常有用,能防止某一個鍵被不小心改寫或覆蓋。
注意,Symbol 值作爲對象屬性名時,不能用點運算符。
const mySymbol = Symbol();
const a = {};
a.mySymbol = 'Hello!';
a[mySymbol] // undefined
a['mySymbol'] // "Hello!"
3.屬性名的遍歷
Symbol 作爲屬性名,該屬性不會出現在for...in
、for...of
循環中,也不會被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回。但是,它也不是私有屬性,有一個Object.getOwnPropertySymbols
方法,可以獲取指定對象的所有 Symbol 屬性名。
Object.getOwnPropertySymbols
方法返回一個數組,成員是當前對象的所有用作屬性名的 Symbol 值。
4.Symbol.for(),Symbol.keyFor()
有時,我們希望重新使用同一個 Symbol 值,Symbol.for
方法可以做到這一點。它接受一個字符串作爲參數,然後搜索有沒有以該參數作爲名稱的 Symbol 值。如果有,就返回這個 Symbol 值,否則就新建並返回一個以該字符串爲名稱的 Symbol 值。
ymbol.for()
與Symbol()
這兩種寫法,都會生成新的 Symbol。它們的區別是,前者會被登記在全局環境中供搜索,後者不會。Symbol.for()
不會每次調用就返回一個新的 Symbol 類型的值,而是會先檢查給定的key
是否已經存在,如果不存在纔會新建一個值。比如,如果你調用Symbol.for("cat")
30 次,每次都會返回同一個 Symbol 值,但是調用Symbol("cat")
30 次,會返回 30 個不同的 Symbol 值。
5.實例:模塊的Singleton模式
Singleton 模式指的是調用一個類,任何時候返回的都是同一個實例。
6.內置的Symbol值
(1)Symbol.hasInstance
對象的Symbol.hasInstance
屬性,指向一個內部方法。當其他對象使用instanceof
運算符,判斷是否爲該對象的實例時,會調用這個方法。比如,foo instanceof Foo
在語言內部,實際調用的是Foo[Symbol.hasInstance](foo)
。
(2)Symbol.isConcatSpreadable
對象的Symbol.isConcatSpreadable
屬性等於一個布爾值,表示該對象用於Array.prototype.concat()
時,是否可以展開。
(3)Symbol.species
對象的Symbol.species
屬性,指向一個構造函數。創建衍生對象時,會使用該屬性。
(4)Symbol.match
對象的Symbol.match
屬性,指向一個函數。當執行str.match(myObject)
時,如果該屬性存在,會調用它,返回該方法的返回值。
(5)Symbol.replace
對象的Symbol.replace
屬性,指向一個方法,當該對象被String.prototype.replace
方法調用時,會返回該方法的返回值。
(6)Symbol.search
對象的Symbol.search
屬性,指向一個方法,當該對象被String.prototype.search
方法調用時,會返回該方法的返回值。
(7)Symbol.split
對象的Symbol.split
屬性,指向一個方法,當該對象被String.prototype.split
方法調用時,會返回該方法的返回值。
(8)Symbol.iterator
象的Symbol.iterator
屬性,指向該對象的默認遍歷器方法。
(9)Symbol.toPrimitive
對象的Symbol.toPrimitive
屬性,指向一個方法。該對象被轉爲原始類型的值時,會調用這個方法,返回該對象對應的原始類型值。
- Number:該場合需要轉成數值
- String:該場合需要轉成字符串
- Default:該場合可以轉成數值,也可以轉成字符串
(10)Symbol.toStringTag
對象的Symbol.toStringTag
屬性,指向一個方法。在該對象上面調用Object.prototype.toString
方法時,如果這個屬性存在,它的返回值會出現在toString
方法返回的字符串之中,表示對象的類型。也就是說,這個屬性可以用來定製[object Object]
或[object Array]
中object
後面的那個字符串。
(11)Symbol.unscopables
對象的Symbol.unscopables
屬性,指向一個對象。該對象指定了使用with
關鍵字時,哪些屬性會被with
環境排除。