1、概述:
ES6 引入了一种新的原始数据类型Symbol
,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined
、null
、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
那么它产生的原因是什么呢?或者说它有什么作用?
在ES5中对象属性名都是字符串形式,这就难免会产生命名冲突的问题,为了防止属性名的冲突,所以Symbol诞生。
let a = Symbol();
let b = Symbol();
console.log(a===b);//false
以上代码用
Symbol
声明了两个变量,通过比较显然它们两个是不相等的。
Symbol函数可以接收一个字符串作为参数,用来对Symbol实例的描述,主要是为了转成字符串的时候好区分他们。注意:如果你给的参数是一样的,那么他们还是不相等的,参数只是对Symbol值的描述。
let a = Symbol("a");
let b = Symbol("b");
如果 Symbol 的参数是一个对象,就会调用该对象的
toString
方法,将其转为字符串,然后才生成一个 Symbol 值。
const obj = {
toString() {
return 'abc';
}
};
const sym = Symbol(obj);
sym // Symbol(abc)
2.与其他数据类型之间的转换
Symbol值不能与其他类型的值进行计算,否则会报错。
let sym = Symbol('My symbol');
"your symbol is " + sym
// TypeError: can't convert symbol to string
`your symbol is ${sym}`
// TypeError: can't convert symbol to string
Symbol 值可以显式转为字符串。
let sym = Symbol('My symbol');
String(sym) // 'Symbol(My symbol)'
sym.toString() // 'Symbol(My symbol)'
Symbol值可以转化为布尔类型的值,但不能转为数值。
let sym = Symbol();
Boolean(sym) // true
!sym // false
if (sym) {
// ...
}
Number(sym) // TypeError
sym + 2 // TypeError
3.Symbol作为对象的属性值
用Symbol作为对象的属性名的时候,可以保证不会出现同名的属性,这对于对象来说非常重要。下面是Symbol作为对象属性名的几种写法:
let mySymbol = Symbol();
// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';
// 第二种写法
let a = {
[mySymbol]: 'Hello!'
};
// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
但是在使用中有个主意点:Symbol作为属性名的时候,对象不能通过点运算符来获取它的属性值。
const mySymbol = Symbol();
const obj = {};
obj .mySymbol = 'Hello!';
obj [mySymbol] // undefined
obj ['mySymbol'] // "Hello!"
上面通过点运算符把mySymbol作为属性名进行对属性赋值操作,因为 点操作符后面总是字符串 ,导致了以Symbol类型作为属性的值还是为默认的undefined。