Symbol基础
Symbol是ES6中新增的一种原始数据类型(其他原始数据类型分别是:Undefined,Null,String,Number,Boolean,Object),表示唯一值。在ES6中,一个对象的属性名既可以是字符串,也可以是Symbol类型;当我们用Symbol当做一个独一无二的标识时,可以简单地理解为它是一个字符串,当然,Symbol不是一般的对象,不能为其添加属性。
1 | let foo = Symbol(); |
注意定义一个Symbol类型的变量时不需要使用new关键字;通过Symbol返回的类型是'symbol'
。
Symbol函数可以接受一个字符串作为参数,用于描述一个Symbol,但即使两个Symbol的描述是相同的,也不表示他们相等。
1 | let foo = Symbol(); |
此外Symbol函数也可以接受一个对象作为参数,不过该对象会被toString()
方法转化为字符串。Symbol类型的变量不能直接参与计算,也不能显式转换为数值,但可以显式转换为字符串或者布尔值。
作为属性名
1 | var sym = Symbol('foo'); |
作为属性名的用法一般是用扩展对象字面量(即中括号的形式)定义。
替代Magic String
Magic String是代码中和程序耦合度较高的字符串,一般来说为了便于维护,我们会在一个程序或者一个系统中将Magic String统一写在一个地方,将其作为常量储存起来,但是大多数时候这些常量的内容并没有太多实际意义,我们需要的只是一个唯一标识符,这个时候我们就可以使用Symbol代替Magic String。
来看如下代码(示例来自参考3)。
1 | function getArea(shape, options) { |
我们看到'Triangle'
这个字符串这样直接放在代码中难以维护,这里虽然只用到了两次,但在规模更大的程序或者工程中可能出现更多次,而当这样的字符串大量存在时,维护这样的代码将是灾难性的。因此我们可以考虑将其抽取出来,放在一个专门保存常量的地方。
但同时,存储的这个常量的具体值对程序并没有实际意义,这里我们就可以考虑采用Symbol。代码如下所示。
1 | // const.js |
1 | // main.js |
全局Symbol
在上面代替常量的小节中,我们仍然使用模块的导入导出方式来使用Symbol。实际上还有一种方式,只要保证Symbol在某处(一般是系统启动的时候被执行的某个文件,类似于上面的const.js)执行了,它就会作为全局常量保存起来,然后我们可以通过Symbol.for方法来获取该常量。
1 | Symbol.for('foo'); // 创建一个全局Symbol |
为了避免命名冲突,建议给描述字符串的加一个前缀。
1 | Symbol.for('io.ouyang.foo'); |
其他
此外Symbol还能用于辅助实现JavaScript中OOP中的私有属性,本文不再详述。读者可以阅读参考和后面有关JavaScript中OOP的专门的笔记。
知识点总结
- Symbol是一种表示的是独一无二的值新的原始数据类型;
- Symbol的定义方法和基本用法;
- Symbol用于表示属性名,替代Magic String。