ES6學習歷程 15 — Symbol
ES6 Symbol
Published in
4 min readApr 7, 2021
ES6新增了Symbol為新的資料型態(Data Types),用來表示獨一無二的值。
創建一個symbol的變數,如下:
let s = Symbol('foo');
Symbol ( ) 內的字串是對此 Symbol的描述,主要是為了在控制台顯示,或者轉為字串時,比較容易區分。
let a1 = Symbol('A');let a2 = Symbol('B');console.log(a1); // Symbol(A)console.log(a2); // Symbol(B)a1.toString(); // "Symbol(A)"a2.toString(); // "Symbol(B)"
上面程式碼中,a1和a2是兩個 Symbol 值。如果不加参數,他們在控制台的輸出都是Symbol(),不利於區分。有了参數後,就等於為他們加上了描述,輸出時就能够分清到底是哪一個值。
建立一個和 a1 同名的 a3,會發現symbol每次創建都是全新且唯一的值:
let a3 = Symbol('A'); // 建立一個和 a1 同名的 a3console.log(a1 === a3); // false
ES2019提供了一個屬性,可以直接回傳Symbol的描述:
const sym = Symbol('hello');sym.description; // "hello"
創建symbol時不需要使用new 關鍵字,否則會出錯:
let s = new Symbol(); // error
symbol可以使用toString()、String() 轉換成字串:
let sym = Symbol('first name');String(sym); // 'Symbol(first name)'sym.toString(); // 'Symbol(first name)'
Symbol.for() / Symbol.keyFor()
o Symbol.for(str) 可以註冊為全域且可重複使用的Symbol值。尋找參數為str的global Symbol,如果存在就直接返回已存在的Symbol值;如果不存在,就新建一個以該參數str為description的Symbol值,並且將其註冊到全域。
Symbol.for(str) 範例:
Symbol.for('foo'); // 若不存在,擇建立一個 global SymbolSymbol.for('foo'); // 已存在,故不會再重複建立,而是會直接返回已存在的 Symbol 值Symbol.for('bar') === Symbol.for('bar'); // trueSymbol('bar') === Symbol('bar'); // falseSymbol.keyFor(param) 用來取得已經存在的全域Symbol值的keyvar globalSym = Symbol.for('foo');Symbol.keyFor(globalSym); // "foo"var localSym = Symbol(); // 必須使用 Symbol.for() 註冊到全域中,才能用keyFor() 找到Symbol.keyFor(localSym); // undefined
Symbol應用
- 作為物件的屬性名稱
由於每個Symbol值都不相等,所以用Symbol當作物件的屬性名稱時,可以確保不會出現同名稱的屬性,這特性可以防止物件的屬性不會在其他地方被意外地覆蓋掉。
let status = Symbol('status');// 寫法一let task = { [status]: 'Hello', description: 'Learn ES6 Symbol'};console.log(task[status]); // Hello// 寫法二let task2 = {}task2[status] = 'Hello2';console.log(task2[status]); // Hello2// 寫法三let task3 = {}Object.defineProperty(task3, status, {value: 'Hello3'});console.log(task3[status]); // Hello3
- 宣告常數值
const FLAG_A = Symbol();const FLAG_B = Symbol();function doSomething(flag) { switch (flag) { case FLAG_A: // … break; case FLAG_B: // … break; default: throw new Error('Undefined flag'); }}