ES6 JavaScript 中的 @@ ("at at") 是什么意思?

70

我注意到在一些关于新的ES6功能的文章页面中使用了@@,但我不知道它究竟是什么意思(它是否实际上是语法或只是一种文档约定)。而且很难搜索到相关信息。能有人解释一下吗?


4
我们可以认同这个看法:知名符号现在更为人所知了吗? :) - Nebula
2
这是一个内部(仅限规范)的惯例,并且它将会改变。 - Bergi
1个回答

54

@@描述了一个被称为“公共符号”的东西。(请注意,在JavaScript中它实际上不是有效的语法。)根据ES6 / ES20151 规范:

公共符号是内置Symbol值,由本规范明确引用算法。它们通常用作属性的键,其值用作规范算法的扩展点。除非另有规定,否则所有代码领域(8.2)共享公共符号值。

代码领域指的是JavaScript环境的不同实例。例如,根文档的代码领域与运行在<iframe>中的JavaScript的代码领域不同。

确定对象是否为数组时,来自哪个代码领域很重要,例如使用instanceof时(提示:如果来自另一帧,则无法正常工作)。为了避免这些类型的问题出现,这些符号是共享的,因此对(例如)@@toString的引用将在对象来自何处时均可正常工作。

其中一些直接通过Symbol构造函数公开,例如@@toPrimitive公开为Symbol.toPrimitive。这可用于在尝试将对象转换为原始值时覆盖生成的值,例如:

let a = { [Symbol.toPrimitive]: () => 1 };
console.log(+a); // 1
console.log(a.valueOf()); // (the same object)
console.log(a.toString()); // "[object Object]"

通常,符号用于为对象提供独特的属性,这些属性不会与随机的属性名称发生冲突,例如:

let a = Symbol();
let foo = { [a]: 1 };
foo[a]; // 1

除了从某个地方获取符号外,没有其他访问值的方法(虽然可以通过调用Object.getOwnPropertySymbols来获取对象的所有符号,但它们不能用于实现私有属性或方法)。

1:请参见此 es-discuss 主题,了解有关不同名称的讨论。


请注意,这并不能解决跨框架的instanceof问题。一个更好的例子是跨框架可迭代数组。 - Bergi
@Bergi:我试图提供一个一般性的跨框架问题示例,但那不是我想表达的意思——也许我会尝试重新措辞。 - Qantas 94 Heavy
@Bergi 这里的“cross-frame”是什么意思? - 1252748
@1252748 跨越框架或iframe - Bergi
@Bergi 那么交叉框架可迭代对象是什么? - 1252748
@1252748 只是在另一个框架中通过代码实例化的数组。甚至可以使用 new (window.frames[0].Array)()/new (iframeElement.contentWindow.Array)() - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接