ECMAScript 6中的Symbol.for(字符串)

Pet*_*ter 10 javascript symbols ecmascript-6

我花了一段时间,但我终于弄明白ECMAScript 6中符号的用途是什么:在将属性附加到共享对象时避免名称冲突 - HTML元素例如(如果你遇到同样的问题,我推荐这篇文章. )

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

(*)是的,我知道符号不是真正的私有,但除此之外.

Ori*_*iol 12

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

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

在下面的示例中,我创建了一个符号来将数据存储在DOM元素中.我可能希望所有其他代码(例如内部原始未编译处理程序)读取该数据.所以我让这个符号全球可用.

var sym = Symbol.for('storeDataInDOM');
document.querySelector('button')[sym] = 'Hello, world!';
Run Code Online (Sandbox Code Playgroud)
<button onclick="alert(this[Symbol.for('storeDataInDOM')])">Click me</button>
Run Code Online (Sandbox Code Playgroud)

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


Ber*_*rgi 6

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

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

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

共享符号似乎完全颠覆了这个概念,而全球注册表则更是如此.

不必要.从那篇文章开始,您读到:" 当多个网页或同一网页中的多个模块需要共享符号时,注册表非常有用. "这些内容的最佳示例是内在符号 - 它们保证跨领域的互操作性,即为什么全局符号注册表比全局范围更全局.

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

实际上还需要不同库之间的互操作性,这些库甚至可能彼此不了解.很好的例子是传感器,代数结构承诺.ES6是否已经在使用中,所有这些都会在全局符号注册表中就共同名称达成一致,而不是依赖于这些字符串或then方法.

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

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

就像您之前使用属性或全局模块对象一样:使用非常长的,非常具有描述性的名称 - 或者通过善意.还有一些命名约定.