符號

符號是「相對新」 這是 ES6 基本版本。符號基元代表不重複的值, 絕對不會與其他值衝突,包括其他符號基元的值。 由相同字元組成的兩個字串基元,嚴格評估 等於:

String() === String()
> true

String( "My string." ) === String( "My string." );
> true

然而,使用 Symbol() 函式建立的任何符號永遠無法 完全等於:

Symbol() === Symbol()
> false

這種特徵可讓您在物件中使用符號做為不重複的屬性鍵,防止 如果與任何其他程式碼的鍵衝突,也可能會新增至該物件。

const mySymbol = Symbol( "Desc" );

const myObject = {

}

myObject
> Object { Symbol("Desc"): "propSymbol" }

符號分為三種類型:

  • 使用 Symbol() 建立的符號
  • 共用符號,由全域符號註冊資料庫設定及擷取 Symbol.for()
  • 「知名符號」定義為符號物件的靜態屬性 這些符號包含無法意外覆寫的內部方法。

Symbol() 可接受將說明 (或「符號名稱」) 做為選用引數。 這些說明是人類可讀的標籤,用於偵錯 不會影響結果的不重複性任何對 Symbol 的呼叫都會傳回 即使多個呼叫具有相同的 說明:

Symbol( "My symbol." ) === Symbol( "My symbol." );
> false

與其他原始資料類型一樣,符號會沿用以下項目的方法和屬性: 原型。舉例來說,您可以將說明當做已建立符號的繼承屬性存取:

let mySymbol = Symbol( "My symbol." );

mySymbol.description
> "My symbol."

但您無法使用 new 關鍵字建立符號:

let mySymbol = new Symbol();

> Uncaught TypeError: Symbol is not a constructor

符號並非列舉性質,因此無法使用符號屬性 建議使用標準方法進行疊代getOwnPropertySymbols() 方法來存取物件的符號屬性。

共用符號

Symbol.for() 方法會嘗試查詢 使用指定字串做為索引鍵的全執行階段全域符號註冊資料庫,並傳回 找出相符的符號如果找不到,系統會建立一個符號 並新增至全域登錄檔:

let sharedSymbol = Symbol.for( "My key." );

sharedSymbol === Symbol.for( "My key." )
> true

這些鍵沒有與指派的說明重疊的功能 由作者建立的 Symbol 基元。如要存取符號註冊資料庫中的符號, 您必須先使用 for() 建立:

Symbol( "String" ) === Symbol( "String" );
> false

Symbol( "String" ) === Symbol().for( "String" );
> false

Symbol().for( "String" ) === Symbol().for( "String" );
> true

如要從符號登錄檔中擷取任何符號的機碼,請使用 Symbol.keyFor():

let mySymbol = Symbol.for( "Key." );

Symbol.keyFor( mySymbol ) ;
> "Key."

「Well-known」符號

已知符號Symbol 物件的靜態屬性, 本身就是符號本身知名符號會為 存取及修改 JavaScript 的內建方法,同時防止核心 避免意外覆寫

Symbol;
> function Symbol()
    asyncIterator: Symbol(Symbol.asyncIterator)
    for: function for()
    hasInstance: Symbol("Symbol.hasInstance")
    isConcatSpreadable: Symbol("Symbol.isConcatSpreadable")
    iterator: Symbol(Symbol.iterator)
    keyFor: function keyFor()
    length: 0
    match: Symbol("Symbol.match")
    matchAll: Symbol("Symbol.matchAll")
    name: "Symbol"
    prototype: Object { … }
    replace: Symbol("Symbol.replace")
    search: Symbol("Symbol.search")
    species: Symbol("Symbol.species")
    split: Symbol("Symbol.split")
    toPrimitive: Symbol("Symbol.toPrimitive")
    toStringTag: Symbol("Symbol.toStringTag")
    unscopables: Symbol("Symbol.unscopables")
    <prototype>: function ()

由於符號是 ES6 的專屬功能,因此這些符號值 也就是用做「擴充點」開發人員修改 JavaScript 也不會產生回溯相容性問題

知名符號值通常採用特殊樣式, @@ 前置字元或包含在 %: 以便區別金鑰與可變動的原型例如:@@match (或 %match%) 是不可變動 Symbol.match 的參照, String.prototype.match

隨堂測驗

可以使用 new 建立符號嗎?

以下何者描述的是 `well-known` 符號?

`Symbol` 物件的靜態屬性
您常用的符號
存取及修改 JavaScript 內容的專屬屬性鍵 內建方法