《深刻理解ES6》筆記——Symbol和Symbol屬性(6)

還記得對象Object嗎?react

let obj = {
  a: 1
}

對象的格式:面試

Object {
    key: value
}

在ES5的時代,對象的key只能是字符串String類型。有人就想搞事,把key改爲其餘數據類型,這不是瞎折騰嗎?ES組織的大神們爲了對付這類搞事的人,就指定了一個新的數據類型:Symbol。segmentfault

原始數據類型

學習Symbol以前,讓咱們回憶一下你曾經用過的原始數據類型,只有5個,別搞錯了。函數

null、undefined學習

是否是面試的時候有人問過你這二者的區別?問這種問題的人很無聊,你要是和他當同事,真是受罪。code

Number 數字類型對象

const a = 10
typeof a // number

String 字符串ip

const a = 'haha'
typeof a // string

boolean 布爾型開發

const a = true, b = false

Symbol

Symbol到底長啥樣?又該怎麼用呢?咱們一塊兒來探索一下。文檔

在MDN文檔中,關於Symbol的說明是這樣的:

Symbol 是一種特殊的、不可變的數據類型,能夠做爲對象屬性的標識符使用。Symbol 對象是一個 symbol primitive data type 的隱式對象包裝器。

symbol 數據類型是一個原始數據類型。

Symbol的語法格式:

Symbol([description]) //description是可選的

建立一個Symbol:

看了Symbol的描述,不知道是什麼鬼?長得像個函數。

咱們開始按照語法建立一個Symbol來研究一下

const name = Symbol();
const name1 = Symbol('sym1');
console.log(name, name1) // Symbol() Symbol(sym1)

Symbol不能使用new

const name = new Symbol(); //不能夠這樣作。
//Symbol is not a constructor

使用Symbol:

使用Number的時候,咱們能夠這樣寫:

const b = Number(10) // 10
//簡寫
const b = 10

同理,使用Symbol,咱們能夠這樣:

const name1 = Symbol('sym1'); // Symbol(sym1)

在全部使用可計算屬性名的地方,都能使用Symbol類型。好比在對象中的key。

const name = Symbol('name');
const obj = {
  [name]: "haha"
}
console.log(obj[name]) // haha

你還可使用Object.defineProperty()和Object.defineProperties()方法。這2個方法是對象的方法,可是做爲Symbol類型key,也不影響使用。

// 設置對象屬性只讀。
Object.defineProperty(obj, name, {writable: false})

這2個方法很是有用,在react源碼中,使用了大量的只讀屬性的對象。如下是從react源碼截取的一段代碼,設置了props對象只讀。可是react仍舊使用字符串做爲key,並不用Symbol。

Object.defineProperty(props, 'key', {
    get: warnAboutAccessingKey,
    configurable: true
  });

Symbol全局共享

Symbol有點特殊,在js文件中定義的Symbol,並不能在其餘文件直接共享。

ES6提供了一個註冊機制,當你註冊Symbol以後,就能在全局共享註冊表裏面的Symbol。Symbol的註冊表和對象表很像,都是key、value結構,只不過這個value是Symbol值。
(key, Symbol)
語法:

Symbol.for() //只有一個參數

還有一個方法是獲取註冊表的Symbol。

語法:

Symbol.keyFor() //只有一個參數,返回的是key

從註冊表獲取全局共享的Symbol

let name = Symbol.for('name');
let name1 = Symbol.for('name1');
let name2 = Symbol.for('name2');

console.log(Symbol.keyFor(name)) // name
console.log(Symbol.keyFor(name1)) // name1
console.log(Symbol.keyFor(name2)) // name2

注意:若是要防止Symbol命名重複問題,能夠加上前綴。如:hyy.name

Symbol與類型強制轉換

JavaScript中的類型能夠自動轉換。好比Number轉換成字符串。

let a = 1;
console.log(typeof a); // number
console.log(a + ' haha') // '1haha'

可是注意了,Symbol不支持這種轉換。Symbol就是這麼拽啊!

let a = Symbol('a');
console.log(typeof a);
console.log(a + ' haha') // Cannot convert a Symbol value to a string

Symbol檢索

在對象中獲取字符串的key時,可使用Object.keys()或Object.getOwnPropertyNames()方法獲取key,可是使用Symbol作key是,你就只能使用ES6新增的方法來獲取了。

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

let obj = {
  [a]: "123",
  [b]: 45
}

const symbolsKey = Object.getOwnPropertySymbols(obj);

for(let value of symbolsKey) {
  console.log(obj[value]) 
}
//"123"
//45

總結

Symbol還提供了多個方法給開發者使用,咱們再也不一一研究每一個方法的用途,你想要了解全面能夠查看 Symbol MDN文檔

咱們只須要知道Symbol如何定義,如何在全局共享,若是在對象中替代key便可應付基本的開發需求了。

最後再回顧一下Symbol是什麼:Symbol是JavaScript的原始數據類型,一個全新的數據類型,和對象、數字、字符串等徹底不同,它必須經過Symbol()建立。它的使用看上面的詳細介紹。

=> 返回文章目錄

相關文章
相關標籤/搜索