1. 程式人生 > >ES6新增的symbol資料型別

ES6新增的symbol資料型別

1、Symbol的概念

在ES5中,物件屬性名都是字串容易造成屬性名衝突。為了避免這種情況的發生,ES6引入了一種新的原始資料型別symbol,表示獨一無二的值。
Symbol() 函式返回的是 symbol 型別的值,該型別具有靜態方法和靜態屬性。

let sy1 = Symbol("winne");
let sy2 = Symbol("winne");

console.log(typeof sy1);  // symbol
console.log(sy1 === sy2); // false

通常,所有symbol是不同的,但有時我們想相同名詞的symbol是相同的。舉例,我們應用不同部分想訪問名詞為"id"的symbol,當然需要是相同的。

使用 Symbol() 函式的語法,不會在你的整個程式碼庫中建立一個可用的全域性 symbol型別。要建立跨檔案可用的symbol,甚至跨域(每個都有它自己的全域性作用域) , 使用Symbol.for("鍵名") 方法會根據給定的鍵 key,來從執行時的 symbol 登錄檔中找到對應鍵名的 symbol,如果找到了,則返回它的值。否則,新建一個與該鍵關聯的 symbol,並放入全域性 symbol 登錄檔中。這樣就保證通過相同名詞重複訪問獲得相同的symbol。

let a1 = Symbol.for('id');
let a2 = Symbol.for('id');

console.
log(a1 === a2); // true

2、Symbol的作用

確保屬性名不同名,且不被覆蓋。

let sy1 = Symbol();
let sy2 = Symbol();
let sy3 = Symbol("name");
let obj = {
    [sy1]:'hi',
    name:"winne",
    id:66,
    [sy3]:"hello"
};
obj[sy2] = "ES6";

console.log(obj);
//{name: "winne", id: 66, Symbol(): "hi", Symbol(name): "hello", Symbol(): "ES6"}

Symbol作為屬性名,該屬性不會出現在 for…in…和 for…of… 迴圈中,也不會被 Object.keys(), Object.getOwnPropertyNames() 返回。

let sy1 = Symbol();
let sy2 = Symbol();
let sy3 = Symbol("name");
let obj = {
    [sy1]:'hi',
    name:"winne",
    id:66,
    [sy3]:"hello"
};
obj[sy2] = "ES6";

for(let key in obj){
    console.log(key);
}
//name
//id

注意:
for…of迴圈不會迴圈物件的key,只會迴圈出陣列的value,因此for…of不能迴圈遍歷普通物件。
如果實在想用for…of來遍歷普通物件的屬性的話,可以通過和Object.keys()搭配使用,先獲取物件的所有key的陣列
然後遍歷:

let sy1 = Symbol();
let sy2 = Symbol();
let sy3 = Symbol("name");
let obj = {
    [sy1]:'hi',
    name:"winne",
    id:66,
    [sy3]:"hello"
};
obj[sy2] = "ES6";
let objKeys = Object.keys(obj);
console.log(objKeys); // ["name","id"]
for(let key of objKeys ){
    console.log(key);
}
//name
//id

3、Object.getOwnPropertySymbols()

返回值是儲存自有Symbol屬性的鍵名陣列。原型鏈上的屬性不會被獲取。

let sy1 = Symbol();
let sy2 = Symbol();
let sy3 = Symbol("name");
let obj = {
    [sy1]:'hi',
    name:"winne",
    id:66,
    [sy3]:"hello"
};
obj[sy2] = "ES6";
let symbols = Object.getOwnPropertySymbols(obj);
console.log(symbols); // [Symbol(), Symbol(name), Symbol()]
symbols.forEach(function(key,index){
    console.log(key,index,obj[key]);
})
// Symbol() 0 "hi"
// Symbol(name) 1 "hello"
// Symbol() 2 "ES6"

3、Reflect.ownKeys()

遍歷出所有的obj物件中的鍵名,包括Symbol鍵名的,返回鍵名的集合陣列。

let sy1 = Symbol();
let sy2 = Symbol();
let sy3 = Symbol("name");
let obj = {
    [sy1]:'hi',
    name:"winne",
    id:66,
    [sy3]:"hello"
};
obj[sy2] = "ES6";
let allKeys = Reflect.ownKeys(obj) ;
console.log(allKeys); // ["name", "id", Symbol(), Symbol(name), Symbol()]
allKeys.forEach(function(key,index){
    console.log(key,index,obj[key]);
})
// "name"    0   "winne"
// "id"      1   66
// Symbol()  2   "hi"
// Symbol(name) 3 "hello"
// Symbol() 4 "ES6"