[每日一題]ES6中爲何要使用Symbol?

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

加入咱們一塊兒學習,day day up面試

做者:saucxs | songEagle算法

來源:原創函數

1、前言

2020.12.23日剛立的flag,每日一題,題目類型不限制。post

點擊下面圖片,查看第1道「一道面試題是如何引起深層次的靈魂拷問?」學習

公衆號「鬆寶寫代碼」每日一題

或者我的站點連接:code

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

接下來是第2道:ES6中爲何要使用Symbol?blog

2、ES6中爲何要使用Symbol?

一、簡述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'。

二、簡述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

三、爲何要使用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。

還有能夠運用在類的私有變量和私有方法中。

福利

一、內推福利

回覆「校招」獲取內推碼

回覆「社招」獲取內推

回覆「實習生」獲取內推

後續會有更多福利

二、學習資料福利

回覆「算法」獲取算法學習資料

三、每日一題

「鬆寶寫代碼」每日一題

或者我的站點連接:

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

The End

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

相關文章
相關標籤/搜索