ES5
的对象属性名
都是字符串
,这容易造成属性名
的冲突。
ES6
引入了一种新的原始数据类型Symbol
,表示独一无二的值
。
它是JavaScript
语言的第七种
数据类型,前六种是:Undefined
、Null
、布尔值(Boolean)
、字符串(String)
、数值(Number)
、对象(Object)
。
Symbol
值通过Symbol函数
生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的Symbol类型。
凡是属性名属于Symbol
类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
let s = Symbol();
console.log(typeof s) // symbol
上面代码中,变量s就是一个独一无二的值。typeof运算符的结果,表明变量s是Symbol数据类型,而不是字符串之类的其他类型。
Symbol
函数可以接受一个字符串
作为参数
,表示对Symbol
实例的描述。这主要是为了在控制台显示或者转为字符串时,比较容易区分。
var s1 = Symbol('foo');
var s2 = Symbol('bar');
console.log(s1,s2) // Symbol(foo) Symbol(bar) 如果不加参数,输出都是Symbol(),不能区分
每个Symbol类型都是独一无二的值
,体现在下面这段代码中:
var a= Symbol("aaa");
var b= Symbol("aaa");
a===b // false a和b是不相等的
Symbol
值不能与其他类型的值进行运算,会报错。但是,Symbol
值可以显式转为字符串。
var sym = Symbol('a symbol');
//两种方法都可以转为字符串
String(sym) // 'Symbol(a symbol)'
sym.toString() // 'Symbol(a symbol)'
由于每一个Symbol
值都是不相等
的,这意味着Symbol
值可以作为标识符
用于对象的属性名,这就能保证不会出现同名的属性。
推荐两种写法:
let name = Symbol();
// 第一种写法
let student= {};
student[name] = 'jack!'; // Symbol值name作为student的属性
// 第二种写法
let student= {
[name]: 'jack!' //注意要使用方括号包裹,不放在方括号中,该属性的键名就是字符串
};
注意:Symbol值作为对象属性名时,不能用点运算符,要使用方括号。
因为点运算符
后面总是字符串
,所以不会读取name作为标识名
所指代的那个值,导致student的属性name名实际上是一个字符串
,而不是一个Symbol值。如以下代码就不是Symbol值作为属性。
student.name= 'jack';
取值对象的Symbol类型的属性也要用方括号。普通属性是直接用点运算符。
3.Symbol
类型还可以用于定义一组常量
,保证这组常量的值都是不相等的。
levels = {
DEBUG: Symbol('debug'),
INFO: Symbol('info'),
WARN: Symbol('warn')
};
console.log(levels.DEBUG) // Symbol(debug)
console.log(levels.INFO) // Symbol(info)
console.log(levels.WARN) // Symbol(warn)
常量
使用Symbol
值最大的好处,就是其他任何值都不可能有相同的值了。
Symbol
的值是唯一的,所以不会出现相同值的常量