@@
描述了一个被称为“公共符号”的东西。(请注意,在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
问题。一个更好的例子是跨框架可迭代数组。 - Berginew (window.frames[0].Array)()
/new (iframeElement.contentWindow.Array)()
。 - Bergi