關注「鬆寶寫程式碼」,精選好文,每日面試題
加入我們一起學習,day day up
作者:saucxs | songEagle
來源:原創
一、前言
2020.12.23日剛立的flag,每日一題,題目型別不限制。
點選下面圖片,檢視第1道「一道面試題是如何引發深層次的靈魂拷問?」
或者個人站點連結:
接下來是第2道:ES6中為什麼要使用Symbol?
二、ES6中為什麼要使用Symbol?
1、簡述ES6中Symbol的概念
ES6中已經有6種資料型別:
- Undefined
- Null
- 布林值
- 字串
- 數值
- 物件
但是在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。
還有可以運用在類的私有變數和私有方法中。
福利
1、內推福利
回覆「校招」獲取內推碼
回覆「社招」獲取內推
回覆「實習生」獲取內推
後續會有更多福利
2、學習資料福利
回覆「演算法」獲取演算法學習資料
3、每日一題
-
本文就是第2道「ES6中為什麼要使用Symbol?」
-
第1道「一道面試題是如何引發深層次的靈魂拷問?」
或者個人站點連結:
The End
songEagle開發知識體系構建,技術分享,專案實戰,實驗室,每日一題,帶你一起學習新技術,總結學習過程,讓你進階到高階資深工程師,學習專案管理,思考職業發展,生活感悟,充實中成長起來。問題或建議,請後臺留言。