symbol是ES6中新增的一种基础数据类型,英文解释: 标记、象征、符号等,为什么要新增这样一种数据类型呢?
1. Symbol出现的原因
假设我们创建一个全局对象,多个模块都要用这个对象,但是我想保证对象的属性是唯一的,这好像有点困难,因为如果是全局对象,那么谁都可以修改它,很有可能就把这个属性给覆盖掉了。
ES6针对JavaScript语法中的这个缺点,提出了一种新的数据类型:Symbol数据类型。它的值是使用Symbol()函数得到的,返回一个在全局作用域中的唯一的、确定的一个值。
let a1 = Symbol(2)
let a2 = Symbol(2)
console.log(a1,a1 === a2, typeof a1) // Symbol(2) false 'symbol'
从上面的结果看,a1和a2是不相等的,这保证了Symbol函数返回值的唯一性。
2. 概念
symbol 是一种基本数据类型 (primitive data type)。
Symbol()
函数会返回symbol类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的symbol注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()
"。每个从
Symbol()
返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据类型仅有的目的。
语法
Symbol([description])
参数是可选的,是字符串类型,对symbol的描述,但不是访问Symbol本身。
3.特征
参数可传可不传,传的话可以作为这个Symbol的标识,像上面的例子;
可以显式转换成字符串或者布尔值,但不能转为数值。
let b1 = Symbol('hello')
console.log(b1.toString()) // Symbol(hello)
console.log(Boolean(b1)) // true
console.log(Number(b1)) // TypeError: Cannot convert a Symbol value to a number
既然不能转化为数值型,那就不能参与运算。
4. 用途
在官方解释中能看到,仅有的目的就是作为对象属性的标识符。
要想把他作为对象属性的标识符,那就要用一个变量定义它,不然不好引用。
let a = Symbol()
var obj = {
[a]: 'zhangsan'
}
console.log(obj[a]) // zhangsan
还有一个大用处,就是消除魔法字符串。
魔法字符串:代码中多次出现,与代码形成强耦合的某一字符串或数值。
function shage(type, option) {
let a = 0
switch (type) {
case 'angle':
a = 0.1
break;
}
return a
}
看上面的代码,这个'angle'就是一个魔法字符串,不利于维护与修改。
改进一下
const shageType = {
angle: Symbol()
}
...
case shageType.angle:
...
从上可以看出,其实shageType.angle的值是什么不重要,只要跟其他属性的值不冲突就行。