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"