ES6中 Symbol

在學習ES6之前已經學過 6 種數據類型,分別是:ObjectNumberStringBooleanNullUndefined
ES6中新增了一種新的原始數據類型:Symbol

1. Symbol 的基本用法

let s = Symbol();
console.log(typeof s) //symbol

2. Symbol 的特點

Symbol 是獨一無二的值。

let s1 = Symbol("zsl");
let s2 = Symbol("zsl");
console.log(s1 === s2) //false
console.log(s1 == s2) //false

//s1 與 s2的Symbol值是一樣的,而且二個的描述值(description)也是一樣的,即便這樣s1 與 s2也不相等。

Symbol 不能與其他數據類型值參與運算。

//下面二種寫法都會報錯
Symbol(1) + 1;
Symbol("ni") + "ni";

3. Symbol 在對象中的應用

let name = Symbol();
let obj = {
	[name]: "zsl"
}
console.log(obj); //{Symbol(): "zsl"}

//獲取屬性值
console.log(obj[name]) //zsl 注意這裏用[],不能obj.name
obj[name] = "zc";
console.log(obj[name]) //zc

Symbol 對 對象元素起到保護作用。

let obj={name:'zsl',skill:'web'};
let age=Symbol();
obj[age]=18;
for (let item in obj){
    console.log(obj[item]); //zsl web
} 
console.log(obj); //{name: "zsl", skill: "web", Symbol(): 18}

這樣使用 Symbol 屬性能對年齡起到保護作用 ,但是 Symbol 並不是私有屬性。

4. Symbol 屬性名的遍歷

Symbol 作爲屬性名,遍歷對象的時候,該屬性不會出現在for...infor...of循環中,也不會被Object.keys()Object.getOwnPropertyNames()JSON.stringify()返回,Symbol不是私有屬性。

const obj = {};
const foo = Symbol('foo');

obj[foo] = 'bar';

for (let i in obj) {
  console.log(i); // 無輸出
}

Object.getOwnPropertyNames(obj) // []
Object.getOwnPropertySymbols(obj) // [Symbol(foo)]

使用for...in循環和Object.getOwnPropertyNames()方法都得不到 Symbol 鍵名,需要使用Object.getOwnPropertySymbols()方法。

另一個新的 API,Reflect.ownKeys()方法可以返回所有類型的鍵名,包括常規鍵名和 Symbol 鍵名。
Reflect.ownKeys(obj)返回一個數組,包含對象自身的所有鍵名,不管鍵名是 Symbol 或字符串,也不管是否可枚舉。

let obj = {
  [Symbol('my_key')]: 1,
  enum: 2,
  nonEnum: 3
};

Reflect.ownKeys(obj)
//  ["enum", "nonEnum", Symbol(my_key)]

Reflect.ownKeys()方法遍歷規則:首先遍歷所有數值鍵,按照數值升序排列。其次遍歷所有字符串鍵,按照加入時間升序排列。最後遍歷所有 Symbol 鍵,按照加入時間升序排列的規則

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