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"

猜你喜欢

转载自blog.csdn.net/m0_38134431/article/details/83897315