[每日一題]ES6中為什么要使用Symbol?


關注「松寶寫代碼」,精選好文,每日面試題

加入我們一起學習,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、每日一題

「松寶寫代碼」每日一題

或者個人站點鏈接:

一道面試題是如何引發深層次的靈魂拷問

The End

songEagle開發知識體系構建,技術分享,項目實戰,實驗室,每日一題,帶你一起學習新技術,總結學習過程,讓你進階到高級資深工程師,學習項目管理,思考職業發展,生活感悟,充實中成長起來。問題或建議,請后台留言。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM