繁体   English   中英

了解ES6符号

[英]Understanding ES6 Symbols

在语言方面,我一直在使用,从C#到Lisp,Scala到Haskell,以及支持它们的每种语言,符号几乎都是一样的。 也就是说,任何两个具有相同名称的符号都保证是相同的,因为它们是单例对象。

球拍:( (equal? 'foo 'foo)真的

Common Lisp :( (eq 'foo 'foo)是的

Ruby :: :foo == :foo true

斯卡拉: 'foo == 'foo真的

ES6: Symbol('foo') === Symbol('foo') false

符号作为单例的好处是显而易见的:你可以在地图/字典中使用它们,而不会冒你的密钥不等于你的输入的风险,因为语言突然决定以不同的方式散列它(看着你,Ruby)

那么为什么ECMAScript 6对此采取不同的方法,我该如何解决它?

您可以(通过使用已注册的(全局)符号(排序)通过名称获得符号“可知”的效果:

var s1 = Symbol.for("foo");
var s2 = Symbol.for("foo");
s1 === s2; // true

当然,您也可以使用Map实例或普通对象创建自己的Symbol注册表。

编辑 - 我将补充说,在创建一个新的Symbol实例时,可选字符串参数的意图是为程序员提供一种识别符号含义和目的的方法。 如果没有该字符串,符号可以作为符号正常工作,但如果在调试器中转储对象,则由此类匿名符号实例键入的属性只是值。 如果您使用符号键在对象上保留数字属性,那么您只会看到一些数字,这会令人困惑。 与Symbol实例关联的描述字符串为程序员提供参考信息,而不会损害Symbol作为键值的唯一性。

最后,您始终可以在两个类似构造的Symbol实例上比较调用.toString()的结果。 怀疑这种做法会被认为是有问题的,但你当然可以这样做。

编辑更多 - 在我看来,JavaScript中Symbol创建的默认行为使得该类型比Erlang中的原子或Clojure中的键更有用 因为默认情况下语言提供的值保证是唯一的,所以命名空间冲突的基本问题很好地解决了。 它仍然可以使用“众所周知的”符号,但具有可用的唯一值,而不必担心可能也希望避免冲突的其他代码的冲突是很好的。 JavaScript具有某种独特的,当然是唯一普遍存在且无法控制的全局命名空间问题,可能被程序员甚至不知道的代码所污染,因为代码可能会因为不同于某一方的行为而在浏览器环境中发生冲突。任意数量的软件架构师,并且不知道。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM