Symbol

241

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的值是什么不重要,只要跟其他属性的值不冲突就行。