第七元素

typeof Symbol(): symbol

Javascript 一共有6種數據類型:Undefined、Null、Number、String、Object、Boolean。今天,咱們先看看第七種:Symbol。api

爲何要產生新的類型

ES5的對象屬性名都是字符串,這容易形成屬性名的衝突。好比,你使用了一個他人提供的對象,但又想爲這個對象添加新的方法(mixin模式),新方法的名字就有可能與現有方法產生衝突。若是有一種機制,保證每一個屬性的名字都是獨一無二的就行了,這樣就從根本上防止屬性名的衝突。這就是ES6引入Symbol的緣由。跨域

可見,這個類型是提供了一個不可更新的特性,這樣能夠保證別人不會覆蓋你的屬性。下面咱們來看看它的樣子:this

語法:Symbol([description])

let mySymbol = Symbol();
let mySymbol2 = Symbol('this is just a desction');

沒有new,裏面的參數只是一個描述,這就是對這個構造器的最簡單解釋了。debug

實際用途

當你第一眼看到Symbol,你會在想,什麼鬼,不想用。當你知道它的特性,會讓你不得不重視它。咱們知道,對象的鍵能夠用數字或字符串,但這樣的話就不能保證惟一性,當咱們知道symbol的特性,就能夠拿它來作試驗了。設計

  1. 能夠做爲鍵名:code

let mySymbol = Symbol();
let obj = {};
obj[mySymbol] = 'hello';

如此簡單的一句,obj對象就使用了mySymbol這個symbol做爲鍵屬性,它是一個symbol,不是一個字符串。你不能用點去訪問它了,相似的,for-in去枚舉一個含有symbol鍵的對象,也不會打印出來(看例子)。既然它的做用就是保證惟一,咱們就能夠在這種需求下知足了。對象

  1. 惟一性ip

let a = 'hello';
let b = 'hello';

console.log( a === b); // true

let a = Symbol('hello');
let b = Symbol('hello');

console.log( a === b); // false

已有的數據類型,咱們很熟悉。再來看看symbol,即便是同樣的描述,它們也是不相同的。作用域

舉一個例子:文檔

  1. 例1

const obj = {
  [Symbol('age')] : 20,
  [Symbol('name')] : 'liya',
  ok: true
}

for( var i in obj) {
  console.log(obj[i]);
}

運行以後,你只會獲得一個true。for-in 並不能訪問到symbol,想要訪問,你必須用到專用的api。

  1. 例2

log.levels = {
    DEBUG: Symbol('debug'),
    INFO: Symbol('info'),
    WARN: Symbol('warn'),
};
log(log.levels.DEBUG, 'debug message');
log(log.levels.INFO, 'info message');

咋看也沒有什麼Symbol的事,事實上在ES5時代,你必須這樣寫:

log.levels = {
    DEBUG: 1,
    INFO: 2,
    WARN: 3,
};

這樣寫的壞處是,值不是惟一的,某天若是被人把DEBUG的值改爲了3,那你不是頓時懵了。用Symbol的好處在於,你不用理會它的值是什麼,它只是一個佔位符,而且惟一。

註冊表

每一個symbol是惟一的,即便兩個描述同樣的symbol也不相等。symbol的弱封裝機制:模塊建立了幾個symbol,能夠在任意對象上使用,無須擔憂與其它代碼建立的屬性產生衝突。它只在當前的做用域生效,若是要在全局中共享,就要在全局中註冊,使用Symbol.for()去註冊。

Symbol('ok');
Symbol.for('ok');

console.log(Symbol('ok') === Symbol('ok'));           // false
console.log(Symbol.for('ok') === Symbol.for('ok'));   // true

第一句和第二句都是建立一個Symbol,不一樣的是,Symbol.for再也不是每次建立不一樣的symbol,它會從註冊表中找,找到了就會返回。不管你訪問幾回,都不會建立新的symbol。全局的symbol能夠跨域和在多個頁面中使用。

最後

查了一些資料,但也不是太過清楚,畢竟用的人還很少。期待在ES6後面可以讓更多人去使用,相似Symbol這種api,你們只是瞄一眼就再也不關注了,除了文檔不夠,更多的是設計上的問題。ES6出了有一段時間,有多少api可以深刻人心,我想只有在坐的各位比較清楚。

相關文章
相關標籤/搜索