1.Symbol是什么?
Symbol是es6新引入的原始数据类型,表示独一无二的值。
Symbol值通过Symbol函数生成:
let s = Symbol()
console.log(typeof s) // "symbol"
2.Symbol的作用
es5的对象属性名都是字符串,这容易造成属性名冲突。新引入的Symbol类型很好地解决了这个问题。只要属性名属于Symbol类型,就是独一无二的,不会与其他属性名产生冲突。
Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述:
let s1 = Symbol('s1');
console.log(s1); // Symbol(s1)
如果Symbol的参数是一个对象,会调用对象的toString方法,并将其转为字符串:
const obj = {a:1,b:2}
const obj2 = {a:1, b:2, toString(){return 'abc'} } //给对象定义了一个toString方法
const arr = ['a','b']
const fun = function(){return 1}
console.log(Symbol(obj)); // Symbol([object Object])
console.log(Symbol(obj2)); // Symbol(abc)
console.log(Symbol(arr)); // Symbol(a,b)
console.log(Symbol(fun)); // Symbol(function(){return 1})
3.Symbol作为对象属性名
const mySymbol = Symbol()
//第一种写法
const a = {}
a[mySymbol] = 'helloA'
//第二种写法
const b = {
[mySymbol]: 'helloB'
}
//第三种写法
const c= {}
Object.defineProperty(c,mySymbol,{ value:'helloC'} )
console.log(a[mySymbol]); //helloA
console.log(b[mySymbol]); //helloB
console.log(c[mySymbol]); //helloC
4.Symbol作为属性名时的遍历
Symbol作为属性名,该属性不会出现在for…in、for…of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()返回。
Object.getOwnPropertySymbols() 返回一个数组,成员是当前对象的所有用作属性名的Symbol值。
Reflect.ownKeys() 可以返回所有类型的键名。
const obj = {a:'a',b:'b'}
const a = Symbol('a')
const b = Symbol('b')
obj[a] = 'helloA'
obj[b] = 'helloB'
for (let i in obj){
console.log(i); // a b
}
console.log(Object.getOwnPropertyNames(obj)); // ['a', 'b']
console.log( Object.getOwnPropertySymbols(obj)); // [Symbol(a), Symbol(b)]
console.log(Reflect.ownKeys(obj)); // ['a', 'b', Symbol(a), Symbol(b)]
5. Symbol.for()、Symbol.keyFor()
当我们希望使用同一个Symbol值,可以使用Symbol.for() 方法。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。有就返回这个Symbol值,没有就新建并返回一个以该字符串为名称的Symbol值。
Symbol.keyFor() 方法返回一个已登记的Symbol类型值的key
const cc = Symbol.for('111')
const dd = Symbol.for('111')
console.log( cc===dd ); //true
console.log(Symbol.keyFor(cc)); //”111“