關注「松寶寫代碼」,精選好文,每日面試題
加入我們一起學習,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開發知識體系構建,技術分享,項目實戰,實驗室,每日一題,帶你一起學習新技術,總結學習過程,讓你進階到高級資深工程師,學習項目管理,思考職業發展,生活感悟,充實中成長起來。問題或建議,請后台留言。