ECMAScript 6

时间:2015-06-22 16:13:13

标签: javascript symbols ecmascript-6

我花了一段时间,但我终于弄明白ECMAScript 6中符号的用途是什么:在将属性附加到共享对象时避免名称冲突 - 例如HTML元素(如果你仍然坚持同一个问题,我建议this article。)

然后我偶然发现了Symbol.for()。显然,ECMAScript 6将维护一个全局符号注册表,您可以通过提供符号描述来使用此函数进行查询。再来?如果我使用符号来避免名称冲突,为什么我要使用除我自己之外的代码来使用它们呢? (*)我如何避免全局注册表中的名称冲突?分享符号似乎完全颠覆了这个概念,而全球注册表则完全颠覆了这一概念。

(*)是的,我知道符号并非真正私有,但除此之外还有。

3 个答案:

答案 0 :(得分:11)

如果您不希望您的符号在GlobalSymbolRegistry中可用,请不要使用Symbol.for

如果您想允许其他代码使用您的符号,请仅使用它。

在下面的示例中,我创建了一个符号来在DOM元素中存储数据。我可能希望其他所有代码(例如Using Step function in animate to transform-rotate an element)都能读取该数据。所以我将符号全局化。



var sym = Symbol.for('storeDataInDOM');
document.querySelector('button')[sym] = 'Hello, world!';

<button onclick="alert(this[Symbol.for('storeDataInDOM')])">Click me</button>
&#13;
&#13;
&#13;

它就像创建全局变量:一般应该避免,但有其优点。但是用符号代替字符串。

答案 1 :(得分:6)

  

如果我使用符号来避免名称冲突,为什么我要使用除我自己之外的代码来使用它们?

这不是符号的唯一用例。其中最重要的两个是:

  • 它们不会与字符串键控属性发生冲突
  • 他们没有通常的机制列举
  

分享符号似乎完全颠覆了这个概念,并且全面地反映了这个概念。

不一定。从that article开始,您读到:“当多个网页或同一网页中的多个模块需要共享符号时,注册表非常有用。”这些的最佳示例是内在符号 - 它们保证跨领域的互操作性,这就是为什么global symbol registry比全局范围更全局化。

例如,您可能有一个加载在网页中的库,一个iframe和一个Web工作者。如果您在这些环境(领域)之间共享数据,则库的所有三个实例都希望使用相同的符号。

实际上还需要不同库之间的互操作性,这些库可能甚至不知道彼此。好例子是transducersalgebraic structurespromises。 ES6是否已经在使用中,所有这些都会在全局符号注册表中就通用名称达成一致,而不是依赖于thesethen方法等字符串。

Another good example将是您的引擎定义的自定义挂钩,例如一个Symbol.inspect = Symbol.for("inspect"),可用于定义console.log使用的自定义字符串化行为。无可否认,该符号不一定需要通过全局符号注册表提供,也可以放在该特定的库对象上(例如console.inspect = Symbole("console.inspect"))。

  

我如何在全局注册表中避免名称冲突?

就像您之前使用属性或全局模块对象一样:使用非常长的,非常具有描述性的名称 - 或者善意。还有some naming conventions

答案 2 :(得分:0)

我发明了Symbol.for()通话最有用的功能。如果您的代码中有时使用符号,则有时在调试时很难使用条件断点。例如,您需要捕获变量是否等于符号类型的值,并且该值绑定在其他模块中。第一个困难的方法是将该值用作常量,然后从该模块导出它。在这种情况下,断点的条件将如下所示:

catchedVariable === exportedSymbolConst

但是最简单的方法是临时更改模块内部的代码,将.for添加到Symbol。然后,您可以编写条件:

catchedVariable === Symbol.for('string_key')

成功调试之后,您将只需删除.for部分即可将代码改回。