(JS基礎)Symbol 類型

Symbol 類型是 ES6 引入的一種數據類型,表示獨一無二的值,是 JavaScript 語言的第七種數據類型。
javascript

目前我所瞭解的兩個用途:java

  • 做爲屬性名或變量名,避免重名帶來的問題;
  • 做爲內置對象的特定方法的屬性名,方便開發者對其改寫。


Symbol 值的建立

Symbol 值建立的方法有兩種,下面逐一介紹。函數

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.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 做爲屬性名的注意事項

遍歷方法中的 Symbol 屬性值

使用 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複製代碼


內置的 Symbol 值

ES6 還提供了 11 個內置的 Symbol 值,指向語言內部使用的方法,當開發者須要修改指定的原生方法時會用到。下面簡單列舉,具體請查閱MDN文檔對象

Symbol.hasInstance

對象的Symbol.hasInstance屬性,指向一個內部方法。當其餘對象使用instanceof運算符,判斷是否爲該對象的實例時,會調用這個方法。ip

Symbol.isConcatSpreadable

對象的Symbol.isConcatSpreadable屬性等於布爾值,表示該對象用於Array.prototype.concat()時,是否能夠展開。

Symbol.species

對象的Symbol.species屬性,指向一個構造函數。建立衍生對象時,會使用該屬性。

Symbol.match

對象的Symbol.match屬性,指向一個函數。當執行str.match(myObject)時,若是該屬性存在,會調用它,返回該方法的返回值。

Symbol.replace

對象的Symbol.replace屬性,指向一個方法,當該對象被String.prototype.replace方法調用時,會返回該方法的返回值。

Symbol.search

對象的Symbol.search屬性,指向一個方法,當該對象被String.prototype.search方法調用時,會返回該方法的返回值。

Symbol.split

對象的Symbol.split屬性,指向一個方法,當該對象被String.prototype.split方法調用時,會返回該方法的返回值。

Symbol.iterator

對象的Symbol.iterator屬性,指向該對象的默認遍歷器方法。

Symbol.toPrimitive

對象的Symbol.toPrimitive屬性,指向一個方法。該對象被轉爲原始類型的值時,會調用這個方法,返回該對象對應的原始類型值。

Symbol.toStringTag

對象的Symbol.toStringTag屬性,指向一個方法。在該對象上面調用Object.prototype.toString方法時,若是這個屬性存在,它的返回值會出如今toString方法返回的字符串之中,表示對象的類型。也就是說,這個屬性能夠用來定製[object Object][object Array]object後面的那個字符串。

Symbol.unscopables

對象的Symbol.unscopables屬性,指向一個對象。該對象指定了使用with關鍵字時,哪些屬性會被with環境排除。

相關文章
相關標籤/搜索