js Symbols類型

1.Symbols 是ECMAScript 2015新增的基本數據類型, (其他的基本數據類型是Undefined、Null、Boolean、Number 和 String)
let a = Symbol("1");
通過調用函數Symbol,傳入字符串爲參數,會返回一個Symbol類型的值
console.dir(typeof Symbols)  //function
console.dir(typeof a)        //symbol
console.dir(a)                 //Symbol(1)

2.可以理解爲他是一種特殊的字符串,每一個Symbol變量的值是不同的,即使傳入的字符串是一樣的
let a = Symbol("1");
let b = Symbol("1");
a===b //false  (===類型相同,且值相同,但是同類型的Symbol變量值不同,它是唯一的)

3.現在我不想調用Symbol函數時,傳的參數是字符串,我們測試一下
let a = Symbol(1);
console.dir(a);              //Symbol(1)
let a = Symbol([1,2,3]);
console.dir(a);              //Symbol(1,2,3)
let a = Symbol({a:1});
console.dir(a);              //Symbol([object Object])
所以可以看出來,參數如果不是字符串,他會被強制轉化成字符串

3.他跟Number() 這些一樣,可以理解爲強制轉化字符串爲Symbols 類型

4.他不能被new ,雖然它是一個函數,但是按道理什麼函數都可以被new,但是mdn上有一段話
圍繞原始數據類型創建一個顯式包裝器對象從 ECMAScript 6 開始不再被支持。 然而,現有的原始包裝器對象,如 new Boolean、new String以及new Number,因爲遺留原因仍可被創建。
也就是說es6開始,不能用原始類型來new,但是前面的那些可以new出一個對象,是歷史遺留問題

5.像字符串一樣,symbol也可以被用做對象屬性的鍵
也就是現在對象的屬性名可以有兩種了,一種是字符串,一種是symbols
let sym = Symbol();
let obj = { [sym]: "value" };
console.log(obj[sym]); // "value"
這裏初始化對象,用中括號[] 擴住了一個變量,這是es6的對象擴展,詳情見es6,大致說明一下,
中括號中的變量除了Symbol類型外,都會被強轉成字符串,那就有一點就要注意,如果中括號中的變量是對象,
let a = {a:1};
let b = {b:1};
let c = {[a]:1,[b]:2};
console.log(c);     //[object Object]:2
你會發現對象中只有一個屬性[object Object]值爲2,因爲無論什麼對象被轉成字符串時,都是[object Object],所以初始化c時,
被覆蓋咯

6.我們來試一下,相同字符串創建的symbol和字符串作爲key創建的對象會覆蓋麼
let a = Symbol("1");
let b = Symbol("1");
let c = "Symbol(1)";
let d = {
  [a]:1,
  [b]:2,
  [c]:3
};
console.log(d);        //Symbol(1):3Symbol(1):1Symbol(1):2
我們發現三個屬性同名,但是都在,說明是不同的屬性

7.關鍵是事情來了,我爲什麼要去查Symbol這個東西呢,是因爲我在看map set 這些類型時,它說:
遍歷Array可以採用下標循環,遍歷Map和Set就無法使用下標。爲了統一集合類型,ES6標準引入了新的iterable類型,Array、Map和Set都屬於iterable類型。
具有iterable類型的集合可以通過新的for ... of循環來遍歷。
那麼我就問了,怎麼看一個對象他是屬於iterable類型呢,然後我就發現了Symbol.iterator,我打印出map,array找它的屬性,我發現他們都有Symbol.iterator這個屬性,Symbol.iterator這個東西幹嘛用的呢,他是一個屬性名,屬性名類型是Symbol。
當一個對象實現了 Symbol.iterator 屬性時,我們認爲它是可迭代的。 一些內置 的類型 如 Array , Map , Set , String , Int32Array , Uint32Array 等都已 經實現了各自的 Symbol.iterator 。 對象上的 Symbol.iterator 函數負責返 回供迭代的值
for..of 會遍歷可迭代的對象,調用對象上的 Symbol.iterator 方法。
(順便講一句,那爲什麼js要加入map這個東西呢)
JavaScript的對象有個小問題,就是鍵必須是字符串。但實際上Number或者其他數據類型作爲鍵也是非常合理的。
爲了解決這個問題,最新的ES6規範引入了新的數據類型Map

8.for in 無法遍歷出symbol屬性
for...in循環:只遍歷對象自身的和繼承的可枚舉的屬性。
Object.keys():返回對象自身的所有可枚舉的屬性的鍵名。
詳情查看es6

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章