Symbol

This glossary page describes both a data type, called "symbol", and the class-like function, called "Symbol()", that (among other things) creates instances of the symbol data type.

The data type "symbol" is a primitive data type having the quality that values of this type can be used to make object properties that are anonymous.  This data type is used as the key for an object property when the property is intended to be private, for the internal use of a class or an object type.  For example, keys of type symbol exist in various built-in JavaScript objects.  Similarly, custom classes can also create private members this way.  The symbol data type is highly specialized in purpose, and remarkable for its lack of versatility; an instance of Symbol can be assigned to an L-value, it can be examined for identity, and that's all; no other operators apply.  (Contrast this with an instance of "Number", for example the integer "42",  which has a panoply of operators that compare or combine the value with others of its type.)

A value having the data type "symbol" can be referred to as a "symbol value."  In the JavaScript run-time environment, a symbol value is created by invoking the function Symbol(), which dynamically produces an anonymous, unique value.  The only sensible usage is to store the symbol and then use the stored value to create an object property.  The following example stores the symbol in a "var".

var  myPrivateMethod  = Symbol();
this[myPrivateMethod] = function() {...};

When a symbol value is used as the identifier in a property assignment, the property (like the symbol) is anonymous; and also is non-enumerable.  Because the property is non-enumerable, it will not show up as a member in the loop construct "for( ... in ...)", and because the property is anonymous, it will not show up in the result array of "Object.getOwnPropertyNames()".  The property can be accessed by using the original symbol value that created it, or by iterating on the result array of "Object.getOwnPropertySymbols() ".  In the prior code example, access to the property will be through the value that was stored in the myPrivateMethod variable.

The built in function "Symbol()" is an incomplete class that returns a symbol value when called as a function, that throws an error upon attempts to use it as a constructor with the syntax "new Symbol()", that has static methods for accessing JavaScript's global symbol table, and that has static properties for addressing certain symbols that are present in commonly used objects.  The creation of symbol values by the Symbol() function was explained above.  The throwing of an error upon attempts to use Symbol() as a constructor is explained as a precaution against the accidental creation of an object that might cause confusion.  The methods that access the global symbol registry are "Symbol.for()" and "Symbol.keyFor()"; these mediate between the global symbol table (or "registry") and the run-time environment.  The symbol registry is mostly built by JavaScript's compiler infrastructure, and the symbol registry's content is not available to JavaScript's run-time infrastructure, except through these reflective methods. The method Symbol.for("tokenString") returns a symbol value from the registry, and Symbol.keyFor(symbolValue) returns a token string from the registry; each is the other's inverse, so the following is true:

Symbol.keyFor(Symbol.for("tokenString"))=="tokenString";  // true

The Symbol class has some static properties that have the ironic effect of naming the anonymous. There are only a few of these; they are for some so-called "well known" symbols.  These are symbols for some selected method properties that are found in certain built in objects.  The exposure of these symbols makes it possible to have direct access to these behaviors; such access might be useful, for example, in the definition of a custom class.  Examples of well-known symbols are: "Symbol.iterator" for array-like objects, and "Symbol.search" for string objects. 

The Symbol() function and the symbol values it creates might be useful to programers designing a custom class.  Symbol values provide a way by which custom classes can create private members, and maintain a symbol registry that pertains just to that class.  A custom class can use symbol values to create "own" properties that are shielded from unwanted, casual discovery.  Within the class definition, the dynamically created symbol value is saved to a scoped variable, available only privately within the class definition.  There is no token string; the scoped variable plays the equivalent role of a token.  

In some programming languages the symbol data type is referred to as an "atom."  

In JavaScript, Symbol is a primitive value.

Symbol can have an optional description, but for debugging purposes only.

Symbol type is a new feature in ECMAScript 2015 and there is no ECMAScript 5 equivalent for symbol.

Symbol("foo") !== Symbol("foo")
const foo = Symbol()
const bar = Symbol()
typeof foo === "symbol"
typeof bar === "symbol"
let obj = {}
obj[foo] = "foo"
obj[bar] = "bar"
JSON.stringify(obj) // {}
Object.keys(obj) // []
Object.getOwnPropertyNames(obj) // []
Object.getOwnPropertySymbols(obj) // [ Symbol(), Symbol() ]

Learn more

General knowledge

Document Tags and Contributors

 Last updated by: afeder,