Symbol 數據類型函數
let s = Symbol(); typeof s; // "symbol"
是 ES6 繼 Number,String,Boolean,Undefined,Null 以後引入的新數據類型spa
對象的屬性名如今能夠有兩種類型,一種是原來就有的字符串,另外一種就是新增的 Symbol 類型。設計
Symbol
函數的參數只是表示對當前 Symbol 值的描述code
let s1 = Symbol('foo'); let s2 = Symbol('bar'); s1 // Symbol(foo) s2 // Symbol(bar) s1.toString(); // "Symbol(foo)" s2.toString(); // "Symbol(bar)"
凡是屬性名屬於 Symbol 類型,就都是獨一無二的,能夠保證不會與其餘屬性名產生衝突。對象
背景:blog
ES5 的對象屬性名都是字符串,這容易形成屬性名的衝突ip
若是有一種機制,保證每一個屬性的名字都是獨一無二的就行了,這樣就從根本上防止屬性名的衝突。字符串
Symbol
表示獨一無二的值。get
它是 JavaScript 語言的第七種數據類型iframe
Symbol 值能夠顯式轉爲字符串
Symbol 值能夠顯式轉爲布爾值
即便 Symbol
函數參數相同,可是它們是不相等的。在對象的內部,使用 Symbol 值定義屬性時,Symbol 值必須放在方括號之中
let s = Symbol(); let obj = { [s]: function (arg) { ... } }; obj[s](123);
switch
語句會按設計的方式工做const COLOR_RED = Symbol(); const COLOR_GREEN = Symbol(); function getComplement(color) { switch (color) { case COLOR_RED: return COLOR_N: return COLOR_GREEN; case COLOR_GREERED; default: throw new Error('Undefined color'); }; };
const shapeType = { triangle: Symbol(), }; function getArea(shape, options) { let area = 0; switch (shape) { case shapeType.triangle: area = .5 * options.width * options.height; break; }; return area; }; getArea(shapeType.triangle, { width: 100, height: 100 });
for...in
、for...of
循環中,也不會被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回Object.getOwnPropertySymbols()
獲取指定對象的全部 Symbol 屬性名。接受一個字符串做爲參數,而後搜索有沒有以該參數做爲名稱的 Symbol 值。
let s1 = Symbol.for('foo'); // 登記在全局環境中供搜索 let s2 = Symbol.for('foo'); // 登記在全局環境中供搜索 s1 === s2 // true
Symbol.for()
與Symbol()
這兩種寫法,都會生成新的 Symbol。
它們的區別是:
前者會被登記在全局環境中供搜索,後者不會。
Symbol.for()
不會每次調用就返回一個新的 Symbol 類型的值,而是會先檢查給定的key
是否已經存在,若是不存在纔會新建一個值。
好比,若是你調用Symbol.for("cat")
30 次,每次都會返回同一個 Symbol 值,
可是調用Symbol("cat")
30 次,會返回 30 個不一樣的 Symbol 值
Symbol.keyFor
() 返回一個已登記的 Symbol 類型值的 key,即 Symbol.for() 生成的 Symbol 值
注意: 爲 Symbol 值登記的名字,是全局環境的,能夠在不一樣的 iframe 或 service worker 中取到同一個值
let obj = { [Symbol('my_key')]: 1, enum: 2, nonEnum: 3 }; Reflect.ownKeys(obj); // ["enum", "nonEnum", Symbol(my_key)]