Symbol 類型是 ES6 引入的一種數據類型,表示獨一無二的值,是 JavaScript 語言的第七種數據類型。
javascript
目前我所瞭解的兩個用途:java
Symbol 值建立的方法有兩種,下面逐一介紹。函數
Symbol 值能經過Symbol
函數生成,要注意的是,Symbol 類型沒有構造函數,即便用new Symbol()
會報錯。此方法建立的 Symbol 值永遠不會有相等的。
測試
let s1 = Symbol();
// let s = new Symbol(); // 錯誤例子
// 能夠傳入字符串做爲參數
let s2 = Symbol('foo');
// 即便傳入相同的字符串,獲得的兩個值仍然是不相等的
console.log(Symbol('foo') === Symbol('foo')); // false
// 經過 toString() 方法能夠獲取該值的字符串量
console.log(s2.toString()); // 'Symbol(foo)'
// 經過實例屬性 description 能夠獲取描述的字符串量
console.log(s2.description); // 'foo'
複製代碼
如例子中的s2
所示,Symbol()
能傳入字符串值做爲描述,且僅能做爲描述,即便是傳入相同的描述字符串,獲得的值仍然不相等。
ui
使用Symbol.for()
方法能夠獲得一個"可能相同"的 Symbol 值,接受一個字符串做爲參數(該值做爲key
,經過keyFor()
方法能夠獲取該值),而後搜索有沒有以該參數做爲名稱的 Symbol 值。若是有,就返回這個 Symbol 值,不然就新建並返回一個以該字符串爲名稱的 Symbol 值。看以下例子:spa
let s1 = Symbol.for('baz');
let s2 = Symbol.for('baz');
console.log(s1 === s2); // true
// 獲取 key 值
console.log(s1.keyFor()); // 'baz'
複製代碼
使用 Symbol 做爲屬性名時,該屬性不會出如今for...in
循環中、Object.entries()
、Object.keys()
、Object.values()
(其對應的屬性值)、Object.getOwnPropertyNames()
、JSON.stringify()
的返回。但它也不是私有屬性。有兩個方法能夠獲取到有關 Symbol 值的屬性:Object.getOwnPropertySymbols
方法,能夠獲取指定對象的全部 Symbol 屬性名(Symbol 類型的值,非字符串量);以及擴展運算符(...
)。下面是測試的結果:prototype
let obj = {
[Symbol()]: 'symbol',
a: 1
}
// 【for...in】
for(let i in obj){
console.log(i); // a (只有a)
}
// 【Object.entries】
let entries = Object.entries(obj);
console.log(entries); // [ [ 'a', 1 ] ]
// 【Object.values】
let values = Object.values(obj);
console.log(values); // [ 1 ]
// 【Object.keys】
let keys = Object.keys(obj);
console.log(keys); // [ 'a' ]
// 【Object.getOwnPropertyNames】
let ownPropNames = Object.getOwnPropertyNames(obj);
console.log(ownPropNames); // [ 'a' ]
// 【JSON.stringify】
console.log(JSON.stringify(obj)); // {"a":1}
// 【Object.getOwnPropertySymbols】
let ownPropSymbols = Object.getOwnPropertySymbols(obj);
console.log(ownPropSymbols); // [ Symbol() ]
// 【展開運算符(...)】
let obj2 = {...obj}
console.log(obj2); // { a: 1, [Symbol()]: 'symbol' }複製代碼
以 Symbol 值做爲屬性名,必須使用[]
運算符定義和獲取屬性值。例子以下:code
let mySymbol = Symbol('foo');
let obj = {
[mySymbol]: 'Symbol',
mySymbol: 'string'
}
console.log(obj.mySymbol); // string
console.log(obj[mySymbol]); // Symbol
console.log(obj['mySymbol']); // string複製代碼
ES6 還提供了 11 個內置的 Symbol 值,指向語言內部使用的方法,當開發者須要修改指定的原生方法時會用到。下面簡單列舉,具體請查閱MDN文檔。對象
對象的Symbol.hasInstance
屬性,指向一個內部方法。當其餘對象使用instanceof
運算符,判斷是否爲該對象的實例時,會調用這個方法。ip
對象的Symbol.isConcatSpreadable
屬性等於布爾值,表示該對象用於Array.prototype.concat()
時,是否能夠展開。
對象的Symbol.species
屬性,指向一個構造函數。建立衍生對象時,會使用該屬性。
對象的Symbol.match
屬性,指向一個函數。當執行str.match(myObject)
時,若是該屬性存在,會調用它,返回該方法的返回值。
對象的Symbol.replace
屬性,指向一個方法,當該對象被String.prototype.replace
方法調用時,會返回該方法的返回值。
對象的Symbol.search
屬性,指向一個方法,當該對象被String.prototype.search
方法調用時,會返回該方法的返回值。
對象的Symbol.split
屬性,指向一個方法,當該對象被String.prototype.split
方法調用時,會返回該方法的返回值。
對象的Symbol.iterator
屬性,指向該對象的默認遍歷器方法。
對象的Symbol.toPrimitive
屬性,指向一個方法。該對象被轉爲原始類型的值時,會調用這個方法,返回該對象對應的原始類型值。
對象的Symbol.toStringTag
屬性,指向一個方法。在該對象上面調用Object.prototype.toString
方法時,若是這個屬性存在,它的返回值會出如今toString
方法返回的字符串之中,表示對象的類型。也就是說,這個屬性能夠用來定製[object Object]
或[object Array]
中object
後面的那個字符串。
對象的Symbol.unscopables
屬性,指向一個對象。該對象指定了使用with
關鍵字時,哪些屬性會被with
環境排除。