20.符号

原文: http://exploringjs.com/impatient-js/ch_symbols.html

符号是通过工厂函数Symbol()创建的原始值:

该参数是可选的,并提供了一个描述,主要用于调试。

一方面,符号就像对象一样,Symbol()创建的每个值都是唯一的,不按值进行比较:

另一方面,它们也表现得像原始值 - 它们必须通过typeof进行分类,它们可以是对象中的属性键:

20.1。符号用例

符号的主要用例是:

  • 定义枚举类型值的常量。
  • 创建唯一的属性键。

20.1.1。符号:枚举式值

假设您要创建表示红色,橙色,黄色,绿色,蓝色和紫色的常量。这样做的一个简单方法是使用字符串:

在正面,记录该常量会产生有用的输出。在负面,存在将颜色的无关值误认为存在风险的风险,因为具有相同内容的两个字符串被认为是相等的:

我们可以通过符号来解决这个问题:

让我们使用符号值常量来实现一个函数:

值得注意的是,如果用'Blue'调用它,该函数会抛出异常:

20.1.2。符号:唯一的属性键

对象中属性(字段)的键在两个级别使用:

  • 该计划在基层运作。它的键反映了问题领域。

  • 库和 ECMAScript 在元级别上运行。例如,.toString是元级别属性键:

以下代码演示了不同之处:

属性.x.y存在于基准级别。它们是point编码的点的坐标,反映了问题域。方法.toString()是元级属性。它告诉 JavaScript 如何对此对象进行字符串化。

元级别和基础级别绝不能发生冲突,这在编程语言生命后期引入新机制时变得更加困难。

符号可用作属性键并解决此问题:每个符号都是唯一的,不会与任何字符串或任何其他符号冲突。

作为一个例子,我们假设我们正在编写一个库,如果它们实现了一个特殊的方法,它会以不同的方式对待它们。这就是定义这种方法的属性键并为对象实现它的方法如下所示:

关于对象的章节中更详细地解释了这种语法。

20.2。众所周知的符号

在 ECMAScript 中扮演特殊角色的符号称为 公知符号 。例子包括:

  • Symbol.iterator:使对象 可迭代 。它是返回迭代器的方法的关键。迭代在其自己的章节中进行了解释。

  • Symbol.hasInstance:自定义instanceof的工作方式。这是该运算符右侧实现的方法的关键。例如:

  • Symbol.toStringTag:影响默认.toString()方法。

    注意:覆盖.toString()通常更好。

20.符号 - 图1 练习:公开的符号

  • Symbol.toStringTagexercises/symbols/to_string_tag_test.js
  • Symbol.hasInstanceexercises/symbols/has_instance_test.js

20.3。转换符号

如果我们将符号sym转换为另一种原始类型会发生什么? TBL。 17 有答案。

Table 17: The results of converting symbols to other primitive types.

转换成 显式转换 强制(隐含转换)
布尔 Boolean(sym) 好的 !sym 好的
Number(sym) TypeError sym*2 TypeError
String(sym) 好的 ''+sym TypeError
sym.toString() 好的 ${sym} TypeError

符号的一个关键缺陷是在将它们转换为其他内容时抛出异常的频率。那背后的想法是什么?首先,转换为数字永远不会有意义,应该加以警告。其次,将符号转换为字符串对于诊断输出确实很有用。但是,警告意外地将符号转换为字符串属性键也是有意义的:

缺点是异常使符号处理更复杂。通过 plus 运算符组装字符串时必须显式转换符号:

20.4。进一步阅读

  • 有关符号(跨领域符号,所有公知符号等)的深入信息,请参阅“探索 ES6”

20.符号 - 图2 测验

参见测验应用程序