答案 0 :(得分:35)
@@
描述了一个众所周知的符号。 (请注意,它在JS中实际上并不是有效的语法。)根据ES6 / ES2015 1 specification:
众所周知的符号是内置符号值,由本规范的算法明确引用。它们通常用作属性的键,其值用作规范算法的扩展点。除非另有说明,否则所有Code Realms(8.2)都会共享众所周知的符号值。
Code Realms是指JavaScript环境的不同实例。例如,根文档的Code Realm将与<iframe>
中运行的JavaScript的Code Realm不同。
一个关于对象来自哪个代码领域的一个例子是在尝试使用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
来获取对象的所有符号,因此它们不能用于实现私有属性或方法)。 / p>
1:有关不同名称的讨论,请参阅this es-discuss topic。