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