
在 JavaScript 中,原始型別有以下幾種:
true, false 兩個值null 的值除了上述的六種原始型別,其餘都是物件型別 Object,包含很常使用的陣列、函式等。
而 Symbol 是 ES6 推出的資料型別,今天就來看個範例了解一下他的用法唄!
Symbol([description])
Symbol 的值都是獨一無二的,可以保證不會跟其他的屬性名產生衝突const bunny = Symbol();
const rabbit = Symbol();
bunny == rabbit; //false
bunny === rabbit; //false
( ) 中加入對此 Symbol 的描述const bunny = Symbol('可愛的小兔子');
const rabbit = Symbol('野兔');
description 取得 Symbol 的描述內容const bunny = Symbol('可愛的小兔子');
bunny.description // "可愛的小兔子"
for 迴圈、for..in 等方法遍歷,需要使用 Object.getOwnPropertySymbols() 方法Symbol 值放在中括號 [],不然會被當字串.取得屬性值,要使用中括號 [ ]
假如我們有個物件 classMate,紀錄同學的資訊,一般會這樣寫:
const classMate = {
  '宜蓁' : { score: 70, sleep: '3:00', drink: true },
  'chita' : { score: 90, sleep: '20:00', drink:false },
  '宜蓁' : { score: 100, sleep: '19:00', drink: false },
}
因為宜蓁這個菜市場名太容易撞名了,班上就剛好有兩位宜蓁同學,我們 console.log classMate 物件看看長怎樣:
哇咧~發現第二個宜蓁資料覆蓋掉第一個宜蓁了QQ~直接被忽略,好可憐,如果去改名又很麻煩,但別擔心,在這時候其實我們就可以使用 Symbol 來解決這個窘境,皆大歡喜:
const classMate = {
  [Symbol('宜蓁')] : { score: 70, sleep: '3:00', drink: true },
  [Symbol('chita')] : { score: 90, sleep: '20:00', drink:false },
  [Symbol('宜蓁')] : { score: 100, sleep: '19:00', drink: false },
}
我們看看 console.log 有啥:
成功囉!Symbol 的值都是唯一的,所以兩位宜蓁的值並不會相等,也就不會有原本的覆蓋問題了,所以 Symbol 可以解決物件屬性中命名衝突的問題!另外在這裡要特別注意,定義屬性鍵名的時候一定要將 Symbol 值放在中括號 [] 裡面,否則屬性的鍵名會當做字串而不是 Symbol 值哦!
如果我們要從物件 classMate 中取得屬性存到 myFriends 時,就需要這樣寫:
const classMate = {
  [Symbol('宜蓁')] : { score: 70, sleep: '3:00', drink: true },
  [Symbol('chita')] : { score: 90, sleep: '20:00', drink:false },
  [Symbol('宜蓁')] : { score: 100, sleep: '19:00', drink: false },
}
const myFriends = Object.getOwnPropertySymbols(classMate).map(item => classMate[item]);
console.log(myFriends);
來 console.log 看一下:
成功取得囉!這邊要注意在取得 Symbol 屬性值的時候不能通過點運算子 . 去訪問,因為點運算子後面要是字串,不會讀取 Symbol 值作為識別符號所指代的值,所以這裡需要用中括號 [] 取得屬性的值。
了解完了 Symbol 的用法,我們來看看 ESLint airbnb 的規則怎麼說:
1.1 Symbols cannot be faithfully polyfilled, so they should not be used when targeting browsers/environments that don’t support them natively.
恩~英文不太好,求大神翻譯囉!
我不是前端工程師,但看了這個Polyfill的單字覺得挺有意思的,就去查了一下:
Symbols cannot be faithfully polyfilled, so they should not be used when targeting browsers/environments that don’t support them natively.
白話一點的意思我想大概是:Symbol這個功能不完全是一個Polyfill,因此在使用時需注意舊版瀏覽器/環境是否有支援。
Polyfill的解釋引用字這:
Polyfill的準確意思為:用於實現瀏覽器並不支援的原生API的程式碼。