What does @@ (“at at”) mean in ES6 JavaScript?

@@ 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.

Leave a Comment