學習 ECMAScript/JavaScript 6 - Symbol
Symbol (符號) 的基本觀念和用途,我在 Name object 草案 一文說明過。在草案階段稱為 Name object ,正式定案後就給了一個通俗的名稱: Symbol ,正式規範的用法可參考 ES6 In Depth: Symbols 。
對以 JavaScript 為主要設計語言的程序人員來說,理解 Symbol 時需要把自己對變數與符號的關係認知,提高一級抽象層次。
Symbol()
ECMAScript/JavaScript 6 正式規範中,將 Symbol (符號) 定為第 7 種原生資料型態。當你想要定義一個符號時,可直接調用 Symbol()
配置。嚴格說來,這樣配置的符號是匿名的符號。例如: let sym = Symbol()
,這樣就會讓符號 sym 聯繫一個匿名符號。
若你在除錯時想印出 sym 的內容時, JavaScript 會告訴你 undefined
。 JavaScript 其實是要告訴你 sym 聯繫的匿名符號並未賦值。而這樣的匿名符號也不能賦值。
前述的程式碼的最後一步,將會賦予另一個值給符號 sym ,這將切斷 sym 和一開始的匿名符號的聯繫關係。
如果你在程式中使用了大量的匿名符號,你除錯時會看到一堆 undefined
的變數,這樣很麻煩。為了提高可讀性, ES6 給了符號一個名為 description 的屬性。你只要在調用 Symbol()
時給它一個字串作為參數即可,例如 let sym = Symbol("key1")
。 description 屬性只有兩個用途,一是用在 toString()
時作為字串內容;二是在 console.log()
顯示在除錯訊息中。注意,當你要在字串操作中使用匿名符號時, JavaScript 不會主動轉型為字串。程序人員必須明確地調用 toString()
才行。還有一點, description 輸出時會是 ‘Symbol(description)’ 的樣子。
看看下列的程式碼範例測試一下自己是否理解為什麼最後的結果是 3 和 2 。
除了最基礎的 Symbol()
外, ES6 正式規範還另外定義了二個符號操作方式。
Symbol.for()
前述的 Symbol()
會配置一個只在定義域(scope)中可用的匿名符號。而 Symbol.for(string)
則會在全域符號表中配置符號,必要的字串參數將成為這個符號在符號表中的鍵。由於有字串鍵可以取得符號,所以不算是匿名符號。這樣的符號可以在不同域中共用。
Symbol.iterator
作為 ES6 iterator (迭代器)的建構方法名稱。
根據 ES6 In Depth: Iterators 的說明,這是牽就 jQuery 而不得不為的語法妥協。因為 jQuery 自訂的迭代器已經使用 ‘iterator’ 作為方法名稱,為了避免和 jQuery 的方法名稱衝突,故 ES6 選擇用 Symbol.iterator
作為 ES6 迭代器的建構方法名稱。
相關文章
- ES6 In Depth: Symbols
- 石頭閒語: ECMAScript/JavaScript6 草案的 Name object
- 石頭閒語: ECMAScript/JavaScript 6 - Template strings
- 石頭閒語: ECMAScript/JavaScript 6 - Symbol
- 石頭閒語: ECMAScript/JavaScript 6 - for-of 與 iterator。
- 石頭閒語: ECMAScript/JavaScript 6 - Generator
- 石頭閒語: ECMAScript/JavaScript 6 - 新函數語法 - Arrow functions, Rest and Spread parameters, Default value
- 石頭閒語: ECMAScript/JavaScript 6 - Destructuring
- 石頭閒語: ECMAScript/JavaScript 6 - var, let 和 const
- 石頭閒語: ECMAScript/JavaScript 6 - Proxy 和 Reflect
- 石頭閒語: ECMAScript/JavaScript 6 - Class
- 石頭閒語: ECMAScript/JavaScript 6 - 語法補遺
- 石頭閒語: ECMAScript/JavaScript 6 - Promise