I've noticed @@
used in a few pages about new ES6 features, but I don't know what exactly it means (whether it's actually syntax or just some kind of documentation convention). And it's hard to google. Can someone explain it?

- 34,206
- 35
- 106
- 163
-
4Can we agree that well-known symbols are now more well known? :) – Nebula Feb 21 '16 at 00:09
-
2It's an internal (spec-only) convention, and [it's going to change](https://github.com/tc39/ecma262/pull/1314) – Bergi Nov 23 '19 at 21:08
1 Answers
@@
describes what's called a well-known symbol. (Note that it isn't actually valid syntax in JS.) According to the ES6/ES20151 specification:
Well-known symbols are built-in Symbol values that are explicitly referenced by algorithms of this specification. They are typically used as the keys of properties whose values serve as extension points of a specification algorithm. Unless otherwise specified, well-known symbols values are shared by all Code Realms (8.2).
Code Realms refer to different instances of a JavaScript environment. For example, the Code Realm of the root document would be different to that of JavaScript running in an <iframe>
.
An example of where it matter what code realm an object comes from is when trying to use instanceof
to determine whether an object is an array (hint: it won't work if it's from another frame). To avoid these kinds of issues from popping up with symbols, they are shared so that references to (say) @@toString
will work no matter where the object came from.
Some of these are exposed directly through the Symbol
constructor, for example, @@toPrimitive
is exposed as Symbol.toPrimitive
. That can be used to override the value produced when attempting to convert an object to a primitive value, for example:
let a = { [Symbol.toPrimitive]: () => 1 };
console.log(+a); // 1
console.log(a.valueOf()); // (the same object)
console.log(a.toString()); // "[object Object]"
In general, symbols are used to provide unique properties on an object which cannot collide with a random property name, for example:
let a = Symbol();
let foo = { [a]: 1 };
foo[a]; // 1
There is no way to access the value except by getting the symbol from somewhere (though you can get all symbols for an object by calling Object.getOwnPropertySymbols
, so they cannot be used to implement private properties or methods).
1: See this es-discuss topic for some discussion about the different names.

- 15,750
- 31
- 68
- 83
-
Notice that this doesn't fix cross-frame `instanceof`. A better example would be cross-frame iterable arrays. – Bergi Apr 07 '15 at 15:05
-
@Bergi: I was trying to provide an example of a cross-frame issue in general, that's not really what I meant -- maybe I'll try and reword that. – Qantas 94 Heavy Apr 07 '15 at 15:06
-
-
-
-
@1252748 Just an array instantiated by code in the other frame. Or even `new (window.frames[0].Array)()`/`new (iframeElement.contentWindow.Array)()` – Bergi Mar 21 '22 at 17:16