還記得對象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到底長啥樣?又該怎麼用呢?咱們一塊兒來探索一下。文檔
在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有點特殊,在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
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
在對象中獲取字符串的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()建立。它的使用看上面的詳細介紹。