ES6中為什麼要使用Symbol?1、簡述ES6中Symbol的概念
ES6中已經有6種資料型別:
UndefinedNull布林值字串數值物件但是在ES6種新加入一種新的資料型別Symbol。
Symbol表示獨一無二的值。
// 沒有引數的情況var s1 = Symbol();var s2 = Symbol();s1 === s2 // false// 有引數的情況var s1 = Symbol('saucxs');var s2 = Symbol('saucxs');s1 === s2 // false
需要說明一下:這裡的字元'saucxs'是該Symbol的一個描述,但是並非兩個引數都是'saucxs'。
2、簡述Symbol的特性特性1:Symbol 值透過 Symbol 函式生成,使用 typeof,結果為 "symbol"var a = Symbol();console.log(typeof a); // "symbol"
特性2:Symbol 函式前不能使用 new 命令,否則會報錯。這是因為生成的 Symbol 是一個原始型別的值,不是物件。特性3:instanceof 的結果為 false
var a = Symbol('foo');console.log(a instanceof Symbol); // false
特性4:Symbol 函式可以接受一個字串作為引數,表示對 Symbol 例項的描述,主要是為了在控制檯顯示,或者轉為字串時,比較容易區分。
var a = Symbol('saucxs');console.log(a); // Symbol(saucxs)
特性5:如果 Symbol 的引數是一個物件,就會呼叫該物件的 toString 方法,將其轉為字串,然後才生成一個 Symbol 值。
const obj = { toString() { return 'abc'; }};const a = Symbol(obj); // Symbol(abc)
特性6:Symbol 函式的引數只是表示對當前 Symbol 值的描述,相同引數的 Symbol 函式的返回值是不相等的。// 沒有引數的情況var s1 = Symbol();var s2 = Symbol();s1 === s2 // false// 有引數的情況var s1 = Symbol('saucxs');var s2 = Symbol('saucxs');s1 === s2 // false
特性7:Symbol 值不能與其他型別的值進行運算,會報錯。
var a = Symbol('saucxs');console.log(`I am ${a}`); // TypeError: can't convert symbol to string
特性8:Symbol 值可以顯式轉為字串。
const f = Symbol('saucxs')f.toString() // "Symbol(saucxs)"String(f) // "Symbol(saucxs)"
特性9:Symbol 值可以作為識別符號,用於物件的屬性名,可以保證不會出現同名的屬性。
var mySymbol = Symbol();// 第一種寫法var a = {};a[mySymbol] = 'Hello!';// 第二種寫法var a = { [mySymbol]: 'Hello!'};// 第三種寫法var a = {};Object.defineProperty(a, mySymbol, { value: 'Hello!' });// 以上寫法都得到同樣結果console.log(a[mySymbol]); // "Hello!"
特性10:Symbol 作為屬性名,該屬性不會出現在 for...in、for...of 迴圈中,也不會被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。但是,它也不是私有屬性,有一個 Object.getOwnPropertySymbols 方法,可以獲取指定物件的所有 Symbol 屬性名。var obj = {};var a = Symbol('a');var b = Symbol('b');obj[a] = 'Hello';obj[b] = 'World';var objectSymbols = Object.getOwnPropertySymbols(obj);console.log(objectSymbols);// [Symbol(a), Symbol(b)]
特性11:使用同一個 Symbol 值,可以使用 Symbol.for。它接受一個字串作為引數,然後搜尋有沒有以該引數作為名稱的 Symbol 值。如果有,就返回這個 Symbol 值,否則就新建並返回一個以該字串為名稱的 Symbol 值。
var s1 = Symbol.for('saucxs');var s2 = Symbol.for('saucxs');console.log(s1 === s2); // true
特性12: Symbol.keyFor 方法返回一個已登記的 Symbol 型別值的 key。
var s1 = Symbol.for("saucxs");console.log(Symbol.keyFor(s1)); // "saucxs"var s2 = Symbol("saucxs");console.log(Symbol.keyFor(s2) ); // undefined
3、為什麼要使用Symbol?比如有這樣一種場景,我們想區分兩個屬性,其實我們並不在意,這兩個屬性值究竟是什麼,我們在意的是,這兩個屬性絕對要區分開來! 例如:
const shapeType = { triangle: 'Triangle'};function getArea(shape, options) { var area = 0; switch (shape) { case shapeType.triangle: area = .5 * options.width * options.height; break; } return area;}getArea(shapeType.triangle, { width: 200, height: 200 });
這個時候,我們僅僅是想區分各種形狀,因為不同的形狀用不同的計算面積的公式。 這裡使用的是triangle的名字叫做‘Triangle’,而是事實上我們不想對triangle去特地取個名,我們只想要區分triangle這個形狀不同於任何其他形狀,那麼這個時候Symbol就派上用場啦!
const shapeType = { triangle: Symbol()};
也就是說,我們不用非要去給變數賦一個字串的值,去區分它和別的變數的值不同,因為去給每個變數取個語義化而又不同的值是一件傷腦子的事,當我們只需要知道每個變數的值都是百分百不同的即可,這時候我們就可以用Symbol。
還有可以運用在類的私有變數和私有方法中。
最新評論