概述
- ES5的对象属性名都是字符串,容易造成属性名的冲突。
Symbol可以保证属性名的独一无二。是一种原始数据类型。ES6中,对象的属性名可以有两种类型,一种字符串,另一种就是新增的Symbol。
let s = Symbol();
typeof s
Symbol()函数不能使用new命令,否则会报错。由于Symbol值不是一个对象,所以也不能添加属性。算是一个类似于字符串的数据类型。
Symbol()函数接收一个字符串作为参数,表示对Symbol实例的描述。两个相同参数的Symbol值也是不相等的。
let s1 = Symbol('s1')
let s2 = Symbol('s2')
s1
s2
let s1 = Symbol();
let s2 = Symbol();
s1 === s2
let s1 = Symbol('foo');
let s2 = Symbol('foo');
s1 === s2
- 如果
Symbol的参数是一个对象,就会调用该对象的toString方法,将其转为字符串,然后才生成一个Symbol值。
let a = {b: 1};
Symbol(a);
Symbol不能与其它类型的值进行运算,会报错。但是可以转为字符串和布尔,但不能转为数值。
let sym = Symbol('symbol');
"your symbol is " + sym
String(sym)
Boolean(sym)
Number(sym)
sym + 2
作为属性名
- 由于每一个
Symbol值都是不相等的,意味着只要Symbol值作为标识符用于对象的属性名,就能保证不会出现同名的属性。作为属性名时,不能用点运算符。
let mySymbol = Symbol()
let obj = {}
obj[mySymbol] = 'Hello'
let obj = {
[mySymbol]: 'Hello'
}
let obj = {};
Object.defineProperty(obj, mySymbol, {value: 'Hello!'});
obj
obj[mySymbol]
obj.mySyobol
属性名的遍历
Symbol不是一个私有属性,但不会被for in、for of、Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
- 可以使用专属方法
Object.getOwnPropertySymbols()获取指定对象的所有Symbol属性名。该方法返回一个数组。
let a = Symbol('a');
let b = Symbol('b');
let obj = {
[a]: 'hello',
[b]: 'world',
c: '!'
}
Object.keys(obj)
Object.getOwnPropertyNames(obj)
Object.getOwnPropertySymbols(obj)
作为常量
- 如果对于常量的值没有要求,只要确保不会跟其他属性值冲突,这时就可以使用
Symbol。
const COLORS = {
black: Symbol(),
yellow: Symbol(),
red: Symbol()
}
function getLevel(color) {
switch (color) {
case (COLORS.black):
return 'the log level -- info'
break;
case (COLORS.yellow):
return 'the log level -- warning'
break;
case (COLORS.red):
return 'the log level -- error'
break;
default:
return 'level is error'
}
}
getLevel(COLORS.black);
getLevel(COLORS.yellow);
实例属性
description
let sym = Symbol('symbol');
sym.description
静态方法
for()
- 接受一个字符串作为参数,全局搜索有没有以该参数作为名称的
Symbol值。如果有就返回这个Symbol值,否则就新建一个以该字符串为描述的Symbol值,并将其登记到全局(无论是不是在函数内创建的)。
let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');
s1 === s2
Symbol.for()与Symbol()都会生成新的Symbol。区别是前者会先在全局环境搜索有没有已存在的,如果未创建就创建一个,并全局登记。而后者不会,后者每调用一次都是生成新的Symbol。
Symbol.for("bar") === Symbol.for("bar")
Symbol("bar") === Symbol("bar")
keyFor()
let s1 = Symbol.for("foo");
Symbol.keyFor(s1)
let s2 = Symbol("foo");
Symbol.keyFor(s2)