在學習ES6之前已經學過 6 種數據類型,分別是:Object
,Number
,String
,Boolean
,Null
,Undefined
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...in
、for...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
鍵,按照加入時間升序排列的規則