我在语言方面遇到过困难,从C#到Lisp,从Scala到Haskell,以及支持它们的所有语言,符号几乎都是一样的。也就是说,任何两个具有相同名称的符号都保证是相同的,因为它们是单例对象。
球拍:(equal? 'foo 'foo)
是真的
Common Lisp:(eq 'foo 'foo)
true
Ruby::foo == :foo
true
Scala:'foo == 'foo
true
ES6:Symbol('foo') === Symbol('foo')
false
符号作为单身人士的好处是显而易见的:你可以在地图/字典中使用它们而不会冒你的密钥不等于你的输入的风险,因为语言突然决定用不同的方式散列它(看着你,Ruby)
那么为什么ECMAScript 6对此采取不同的方法,我该如何解决它呢?
答案 0 :(得分:14)
你可以(排序)获得符号的效果"可知"按名称使用注册(全球)符号:
.toString()
当然,您也可以使用Map实例或普通对象创建自己的Symbol注册表。
编辑 - 我将在制作新的Symbol实例时添加可选字符串参数的意图是提供一种识别符号的含义和目的的方法程序员。如果没有该字符串,符号可以作为符号正常工作,但如果在调试器中转储对象,则由此类匿名符号实例键入的属性只是值。如果您使用符号键在对象上保留数字属性,那么您只会看到一些数字,这会令人困惑。与Symbol实例关联的描述字符串为程序员提供参考信息,而不会影响符号作为键值的唯一性。
最后,您始终可以比较在两个类似构造的Symbol实例上调用conversion = value.to_f * 7.50061
的结果。我怀疑这种做法会被认为是有问题的,但你当然可以这样做。
编辑更多 - 我发现,JavaScript中符号创建的默认行为使得类型更有用,比方说,Erlang中的原子或Clojure中的键。因为默认情况下语言提供的值保证是唯一的,所以命名空间冲突的基本问题很好地解决了。它仍然可以与#34;众所周知的"符号,但有可用的唯一值,而不必担心可能也想避免冲突的其他代码的冲突是很好的。 JavaScript具有某种独特的,当然是唯一普遍存在且无法控制的全局命名空间问题,可能被程序员甚至不知道的代码所污染,因为代码可能会因为不同于某一方的行为而在浏览器环境中发生冲突。任意数量的软件架构师,并且不知道。