Symbol.for(string) in ECMAScript 6
我花了一段时间,但我终于明白了EcmaScript 6中符号的用途:在将属性附加到共享对象时避免名称冲突-HTML元素,例如(如果您遇到同样的问题,我推荐这篇文章)。
但后来我偶然发现了symbol.for()。显然,ECMAScript 6将维护一个全局符号注册表,您可以通过提供符号描述来使用此函数进行查询。再来一次?如果我使用符号来避免名称冲突,为什么我希望自己的代码以外的代码使用它们?(*)如何避免全局注册表中的名称冲突?共享符号似乎完全颠覆了这个概念,全球注册中心也因此受到了双重破坏。
(*)是的,我知道符号不是真正的私密的,但这也不重要。
如果您不想在GlobalSymbolRegistry中使用您的符号,请不要使用
仅当您希望允许其他代码使用您的符号时才使用它。
在下面的示例中,我创建了一个符号来将数据存储在DOM元素中。我可能希望其他所有代码(例如内部原始未编译处理程序)读取该数据。因此,我使符号全局可用。
1 2 | var sym = Symbol.for('storeDataInDOM'); document.querySelector('button')[sym] = 'Hello, world!'; |
1 | <button onclick="alert(this[Symbol.for('storeDataInDOM')])">Click me</button> |
这就像创建全局变量:一般来说应该避免,但有它的优点。但是用符号而不是字符串。
If I use symbols to avoid name collisions, why would I want code other than my own to use them?
这并不是符号唯一的用法。另外两个最重要的是:
- 它们不会与字符串键控属性冲突
- 通常的机械师不计算这些参数。
Sharing of symbols seems to completely subvert the concept and a global registry doubly so.
不一定。就在你读到的那篇文章中,"当多个网页或同一网页中的多个模块需要共享一个符号时,注册表是有用的。"最好的例子是内在符号——它们保证了跨领域的互操作性,这就是为什么全局符号注册表比全局范围更全局的原因。
例如,您可能拥有一个加载在网页、iframe和Web工作者中的库。如果在这些环境(领域)之间共享数据,库的三个实例都将使用相同的符号。
不同的库之间也有一个真正的互操作性需求,这甚至可能不了解彼此。很好的例子是传感器、代数结构或承诺。如果ES6已经在使用,那么所有这些都将在全局符号注册表中商定通用名称,而不是依赖于这样的字符串或
另一个很好的例子是由您的引擎定义的自定义钩子,例如,一个
And how would I avoid name collisions in that global registry?
正如您以前对属性或全局模块对象所做的那样:通过使用非常长、非常描述性的名称-或者出于诚意。还有一些命名约定。
我发明了
1 | catchedVariable === exportedSymbolConst |
但最简单的方法是临时更改模块中添加
1 | catchedVariable === Symbol.for('string_key') |
在成功调试之后,您将更改代码,只需删除