ES5-ES6-ES7_Symbol數據類型

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};
        }
      }
    }
  };
相關文章
相關標籤/搜索