Symbol數據類型簡介數組
ES6 引入了一種新的原始數據類型Symbol,表示獨一無二的值。它是 JavaScript 語言的第七種數據類型,前六種是:undefined、null、布爾值(Boolean)、字符串(String)、數值(Number)、對象(Object)。數據結構
Symbol 值經過Symbol函數生成。這就是說,對象的屬性名如今能夠有兩種類型,一種是原來就有的字符串,另外一種就是新增的 Symbol 類型。函數
凡是屬性名屬於 Symbol 類型,就都是獨一無二的,能夠保證不會與其餘屬性名產生衝突。this
Symbol函數前不能使用new命令,不然會報錯。這是由於生成的 Symbol 是一個原始類型的值,不是對象。spa
也就是說,因爲 Symbol 值不是對象,因此不能添加屬性。基本上,它是一種相似於字符串的數據類型code
let s = Symbol(); //變量s就是一個獨一無二的值。typeof運算符的結果,代表變量s是 Symbol 數據類型,而不是字符串之類的其餘類型 console.log(typeof s); //symbol console.log(s); //Symbol() // Symbol函數能夠接受一個字符串做爲參數,表示對 Symbol 實例的描述, // 主要是爲了在控制檯顯示,或者轉爲字符串時,比較容易區分 let s1 = Symbol('foo'); let s2 = Symbol('bar'); console.log(s1,s2); //Symbol(foo) Symbol(bar) console.log(s1.toString(),s2.toString()); //Symbol(foo) Symbol(bar)
Symbol數據類型的簡單使用對象
//若是 Symbol 的參數是一個對象,就會調用該對象的toString方法,將其轉爲字符串,而後才生成一個 Symbol 值 const obj = { toString() { return 'abc'; } }; const sym = Symbol(obj); console.log(sym); // Symbol(abc) //Symbol函數的參數只是表示對當前 Symbol 值的描述,所以相同參數的Symbol函數的返回值是不相等的。 // 沒有參數的狀況 let s3 = Symbol(); let s4 = Symbol(); console.log(s3 === s4);// false // 有參數的狀況 let s5 = Symbol('foo'); let s6 = Symbol('foo'); console.log(s5 === s6); // false // Symbol 值不能與其餘類型的值進行運算,會報錯 // 可是,Symbol 值能夠顯式轉爲字符串 // Symbol 值也能夠轉爲布爾值,可是不能轉爲數值 let symb = Symbol('My symbol'); //console.log("your symbol is " + symb); // TypeError: can't convert symbol to string console.log(String(symb)); //Symbol(My symbol) console.log(symb.toString()); //Symbol(My symbol) console.log(Boolean(symb)); // true console.log(!symb ); //false //console.log(Number(symb)); // TypeError: Cannot convert a Symbol value to a number //console.log(symb + 2); // TypeError: Cannot convert a Symbol value to a number
做爲對象屬性名的 Symbol blog
因爲每個 Symbol 值都是不相等的,這意味着 Symbol 值能夠做爲標識符,用於對象的屬性名,就能保證不會出現同名的屬性。接口
這對於一個對象由多個模塊構成的狀況很是有用,能防止某一個鍵被不當心改寫或覆蓋,下面有兩種寫法ip
var mySymbol = Symbol('mySymbol'); const obj = {}; obj[mySymbol] = 'hello'; console.log(obj); //{ mySymbol: 'hello' } console.log(obj[mySymbol]); //hello
var mySymbol = Symbol('mySymbol'); const obj = { [mySymbol] : 'hello' } console.log(obj); //{ mySymbol: 'hello' } console.log(obj[mySymbol]) //hello
屬性名的遍歷
Symbol 做爲屬性名,該屬性不會出如今for...in、for...of循環中,也不會被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
var mySymbol = Symbol('mySymbol'); const obj = {userName: 'huang'}; obj[mySymbol] = 'hello'; console.log(obj[mySymbol]) // hello for (let i in obj){ console.log(i) //mySymbol屬性沒有遍歷出來 }
可是,它也不是私有屬性,有一個Object.getOwnPropertySymbols方法,能夠獲取指定對象的全部 Symbol 屬性名
var obj = {}; var a = Symbol('a'); var b = Symbol('b'); obj[a] = 'Hello'; obj[b] = 'World'; //Object.getOwnPropertySymbols方法返回一個數組,成員是當前對象的全部用做屬性名的 Symbol 值。 var objectSymbols = Object.getOwnPropertySymbols(obj); console.log(objectSymbols); //[ Symbol(a), Symbol(b) ]
內置Symbol值
除了定義本身使用的Symbol值之外,ES6還提供了11個內置的Symbol值,指向語言內部使用的方法。
Symbol.iterator——對象的Symbol.iterator屬性,指向該對象的默認遍歷器方法
// 等同於在指定的數據結構內部署了iterator接口 // 當使用for of遍歷某個一個數據結構的時候,首先去找Symbol.iterator,找到了就去遍歷,沒有找到就不能遍歷而且報錯obj is not iterator const obj = { [Symbol.iterator]: function () { let index = 0; return { next: function () { return index < this.length ? {value: this[index++],done: false} : {value: undefined, done: true}; } } } };