1、概述
ES5 的對象屬性名都是字符串,這樣有一個問題是容易造成屬性名的沖突。比如,你使用了一個他人提供的對象,但又想為這個對象添加新的方法(mixin 模式),新方法的名字就有可能與現(xiàn)有方法產(chǎn)生沖突。
如果有一種機制,保證每個屬性的名字都是獨一無二的就好了,這樣就從根本上防止屬性名的沖突,這就是 ES6 引入Symbol的原因。
ES6 引入了一種新的原始數(shù)據(jù)類型Symbol,表示獨一無二的值。它是 JavaScript 語言的第七種數(shù)據(jù)類型,前六種是:undefined、null、布爾值(Boolean)、字符串(String)、數(shù)值(Number)、對象(Object)。
一般Symbol 值通過Symbol函數(shù)生成。這就是說,對象的屬性名現(xiàn)在可以有兩種類型,一種是原來就有的字符串,另一種就是新增的 Symbol 類型。凡是屬性名屬于 Symbol 類型,就都是獨一無二的,可以保證不會與其他屬性名產(chǎn)生沖突。
let s = Symbol();
typeof s // "symbol"
在上面代碼中,變量s就是一個獨一無二的值。typeof運算符的結果,表明變量s是 Symbol 數(shù)據(jù)類型,而不是字符串之類的其他類型。
- 寫一個有參數(shù)和無參數(shù)的Symbol的比較
// 沒有參數(shù)的情況
var s1 = Symbol();
var s2 = Symbol();
s1 === s2 // false
// 有參數(shù)的情況
var s1 = Symbol('foo');
var s2 = Symbol('foo');
s1 === s2 // false
上面的代碼,Symbol函數(shù)的參數(shù)只是表示對當前 Symbol 值的描述,因此相同參數(shù)的Symbol函數(shù)的返回值是不相等的。
2、作為屬性名的Symbol
由于每一個 Symbol 值都是不相等的,這意味著 Symbol 值可以作為標識符,用于對象的屬性名,就能保證不會出現(xiàn)同名的屬性。這對于一個對象由多個模塊構成的情況非常有用,能防止某一個鍵被不小心改寫或覆蓋,下面寫出幾種常見的使用方法
var mySymbol = Symbol();
// 第一種寫法
var a = {};
a[mySymbol] = 'Hello!';
// 第二種寫法
var a = {
[mySymbol]: 'Hello!'
};
// 第三種寫法
var a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
//使用Object.defineProperty,將對象的屬性名指定為一個 Symbol 值。
// 以上寫法都得到同樣結果
a[mySymbol] // "Hello!"
- 需要注意的是:Symbol 值作為屬性名時,該屬性還是公開屬性,不是私有屬性。
以上只簡單的寫了一點關于Symbol的知識,更多參考-阮一峰老師文章