Symbol

The data type symbol is a primitive data type. The Symbol() function returns a value of type symbol, has static properties that expose several members of built-in objects, has static methods that expose the global symbol registry, and resembles a built-in object class, but is incomplete as a constructor because it does not support the syntax "new Symbol()".  

Every symbol value returned from Symbol() is unique.  A symbol value may be used as an identifier for object properties; this is the data type's primary purpose, although other use-cases exist, such as enabling opaque data types, or serving as an implementation-supported unique identifier in general.  Some further explanation about purpose and usage can be found in the glossary entry for Symbol.

Description

To create a new primitive symbol, you write Symbol() with an optional string as its description:

let sym1 = Symbol()
let sym2 = Symbol('foo')
let sym3 = Symbol('foo')

The above code creates three new symbols. Note that Symbol("foo") does not coerce the string "foo" into a symbol. It creates a new symbol each time:

Symbol('foo') === Symbol('foo')  // false

The following syntax with the new operator will throw a TypeError:

let sym = new Symbol()  // TypeError

This prevents authors from creating an explicit Symbol wrapper object instead of a new symbol value and might be surprising as creating explicit wrapper objects around primitive data types is generally possible (for example, new Boolean, new String and new Number).

If you really want to create a Symbol wrapper object, you can use the Object() function:

let sym = Symbol('foo')
typeof sym      // "symbol" 
let symObj = Object(sym)
typeof symObj   // "object"

Shared symbols in the global symbol registry

The above syntax using the Symbol() function will not create a global symbol that is available in your whole codebase. To create symbols available across files and even across realms (each of which has its own global scope), use the methods Symbol.for() and Symbol.keyFor() to set and retrieve symbols from the global symbol registry.

Finding symbol properties on objects

The method Object.getOwnPropertySymbols() returns an array of symbols and lets you find symbol properties on a given object. Note that every object is initialized with no own symbol properties, so that this array will be empty unless you've set symbol properties on the object.

Constructor

Symbol()
Creates a new Symbol object. It is incomplete as a constructor because it does not support the syntax "new Symbol()".

Static properties

Symbol.asyncIterator
A method that returns the default AsyncIterator for an object. Used by for await...of.
Symbol.hasInstance
A method determining if a constructor object recognizes an object as its instance. Used by instanceof.
Symbol.isConcatSpreadable
A Boolean value indicating if an object should be flattened to its array elements. Used by Array.prototype.concat().
Symbol.iterator
A method returning the default iterator for an object. Used by for...of.
Symbol.match
A method that matches against a string, also used to determine if an object may be used as a regular expression. Used by String.prototype.match().
Symbol.matchAll
A method that returns an iterator, that yields matches of the regular expression against a string. Used by String.prototype.matchAll().
Symbol.replace
A method that replaces matched substrings of a string. Used by String.prototype.replace().
Symbol.search
A method that returns the index within a string that matches the regular expression. Used by String.prototype.search().
Symbol.split
A method that splits a string at the indices that match a regular expression. Used by String.prototype.split().
Symbol.species
A constructor function that is used to create derived objects.
Symbol.toPrimitive
A method converting an object to a primitive value.
Symbol.toStringTag
A string value used for the default description of an object. Used by Object.prototype.toString().
Symbol.unscopables
An object value of whose own and inherited property names are excluded from the with environment bindings of the associated object.

Static methods

Symbol.for(key)
Searches for existing symbols with the given key and returns it if found. Otherwise a new symbol gets created in the global symbol registry with key.
Symbol.keyFor(sym)
Retrieves a shared symbol key from the global symbol registry for the given symbol.

Instance properties

Symbol.prototype.description
A read-only string containing the description of the symbol.

Instance methods

Symbol.prototype.toSource()
Returns a string containing the source of the Symbol object. Overrides the Object.prototype.toSource() method.
Symbol.prototype.toString()
Returns a string containing the description of the Symbol. Overrides the Object.prototype.toString() method.
Symbol.prototype.valueOf()
Returns the primitive value of the Symbol object. Overrides the Object.prototype.valueOf() method.
Symbol.prototype[@@toPrimitive]
Returns the primitive value of the Symbol object.

Examples

Using the typeof operator with symbols

The typeof operator can help you to identify symbols.

typeof Symbol() === 'symbol'
typeof Symbol('foo') === 'symbol'
typeof Symbol.iterator === 'symbol'

Symbol type conversions

Some things to note when working with type conversion of symbols.

  • When trying to convert a symbol to a number, a TypeError will be thrown
    (e.g. +sym or sym | 0).
  • When using loose equality, Object(sym) == sym returns true.
  • Symbol("foo") + "bar" throws a TypeError (can't convert symbol to string). This prevents you from silently creating a new string property name from a symbol, for example.
  • The "safer" String(sym) conversion works like a call to Symbol.prototype.toString() with symbols, but note that new String(sym) will throw.

Symbols and for...in iteration

Symbols are not enumerable in for...in iterations. In addition, Object.getOwnPropertyNames() will not return symbol object properties, however, you can use Object.getOwnPropertySymbols() to get these.

let obj = {}

obj[Symbol('a')] = 'a'
obj[Symbol.for('b')] = 'b'
obj['c'] = 'c'
obj.d = 'd'

for (let i in obj) {
   console.log(i)  // logs "c" and "d"
}

Symbols and JSON.stringify()

Symbol-keyed properties will be completely ignored when using JSON.stringify():

JSON.stringify({[Symbol('foo')]: 'foo'})
// '{}'

For more details, see JSON.stringify().

Symbol wrapper objects as property keys

When a Symbol wrapper object is used as a property key, this object will be coerced to its wrapped symbol:

let sym = Symbol('foo')
let obj = {[sym]: 1}
obj[sym]             // 1
obj[Object(sym)]     // still 1

Specifications

Specification
ECMAScript (ECMA-262)
The definition of 'Symbol' in that specification.

Browser compatibility

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
SymbolChrome Full support 38Edge Full support 12
Notes
Full support 12
Notes
Notes Edge 12 included Symbol properties in JSON.stringify() output.
Firefox Full support 36IE No support NoOpera Full support 25Safari Full support 9WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 36Opera Android Full support 25Safari iOS Full support 9Samsung Internet Android Full support 3.0nodejs Full support 0.12
Symbol() constructorChrome Full support 38Edge Full support 12Firefox Full support 36IE No support NoOpera Full support 25Safari Full support 9WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 36Opera Android Full support 25Safari iOS Full support 9Samsung Internet Android Full support 3.0nodejs Full support 0.12
asyncIteratorChrome Full support 63Edge Full support 79Firefox Full support 57IE No support NoOpera Full support 50Safari Full support 11.1WebView Android Full support 63Chrome Android Full support 63Firefox Android No support NoOpera Android Full support 46Safari iOS No support NoSamsung Internet Android Full support 8.0nodejs Full support 10.0.0
descriptionChrome Full support 70Edge Full support 79Firefox Full support 63IE No support NoOpera Full support 57Safari Full support 12.1
Full support 12.1
Partial support 12
Notes
Notes No support for an undefined description.
WebView Android Full support 70Chrome Android Full support 70Firefox Android Full support 63Opera Android Full support 49Safari iOS Full support 12.2
Full support 12.2
Partial support 12
Notes
Notes No support for an undefined description.
Samsung Internet Android Full support 10.0nodejs Full support 11.0.0
forChrome Full support 40Edge Full support 12Firefox Full support 36IE No support NoOpera Full support 27Safari Full support 9WebView Android Full support 40Chrome Android Full support 40Firefox Android Full support 36Opera Android Full support 27Safari iOS Full support 9Samsung Internet Android Full support 4.0nodejs Full support 0.12
hasInstanceChrome Full support 50Edge Full support 15Firefox Full support 50IE No support NoOpera Full support 37Safari Full support 10WebView Android Full support 50Chrome Android Full support 50Firefox Android Full support 50Opera Android Full support 37Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.5.0
Full support 6.5.0
Full support 6.0.0
Disabled
Disabled From version 6.0.0: this feature is behind the --harmony runtime flag.
isConcatSpreadableChrome Full support 48Edge Full support 15Firefox Full support 48IE No support NoOpera Full support 35Safari Full support 10WebView Android Full support 48Chrome Android Full support 48Firefox Android Full support 48Opera Android Full support 35Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0
iteratorChrome Full support 43Edge Full support 12Firefox Full support 36IE No support NoOpera Full support 30Safari Full support 10WebView Android Full support 43Chrome Android Full support 43Firefox Android Full support 36Opera Android Full support 30Safari iOS Full support 10Samsung Internet Android Full support 4.0nodejs Full support 0.12
keyForChrome Full support 40Edge Full support 12Firefox Full support 36IE No support NoOpera Full support 27Safari Full support 9WebView Android Full support 40Chrome Android Full support 40Firefox Android Full support 36Opera Android Full support 27Safari iOS Full support 9Samsung Internet Android Full support 4.0nodejs Full support 0.12
matchChrome Full support 50Edge Full support 79Firefox Full support 40IE No support NoOpera Full support 37Safari Full support 10WebView Android Full support 50Chrome Android Full support 50Firefox Android Full support 40Opera Android Full support 37Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0
matchAllChrome Full support 73Edge Full support 79Firefox Full support 67IE No support NoOpera Full support 60Safari Full support 13WebView Android Full support 73Chrome Android Full support 73Firefox Android Full support 67Opera Android Full support 52Safari iOS Full support 13Samsung Internet Android No support Nonodejs Full support 12.0.0
replaceChrome Full support 50Edge Full support 79Firefox Full support 49IE No support NoOpera Full support 37Safari Full support 10WebView Android Full support 50Chrome Android Full support 50Firefox Android Full support 49Opera Android Full support 37Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0
searchChrome Full support 50Edge Full support 79Firefox Full support 49IE No support NoOpera Full support 37Safari Full support 10WebView Android Full support 50Chrome Android Full support 50Firefox Android Full support 49Opera Android Full support 37Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0
speciesChrome Full support 51Edge Full support 13Firefox Full support 41IE No support NoOpera Full support 38Safari Full support 10WebView Android Full support 51Chrome Android Full support 51Firefox Android Full support 41Opera Android Full support 41Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.5.0
Full support 6.5.0
Full support 6.0.0
Disabled
Disabled From version 6.0.0: this feature is behind the --harmony runtime flag.
splitChrome Full support 50Edge Full support 79Firefox Full support 49IE No support NoOpera Full support 37Safari Full support 10WebView Android Full support 50Chrome Android Full support 50Firefox Android Full support 49Opera Android Full support 37Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0
toPrimitiveChrome Full support 47Edge Full support 15Firefox Full support 44IE No support NoOpera Full support 34Safari Full support 10WebView Android Full support 47Chrome Android Full support 47Firefox Android Full support 44Opera Android Full support 34Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0
toSource
Non-standard
Chrome No support NoEdge No support NoFirefox No support 36 — 74
Notes
No support 36 — 74
Notes
Notes Starting in Firefox 74, toSource() is no longer available for use by web content. It is still allowed for internal and privileged code.
IE No support NoOpera No support NoSafari No support NoWebView Android No support NoChrome Android No support NoFirefox Android Full support 36Opera Android No support NoSafari iOS No support NoSamsung Internet Android No support Nonodejs No support No
toStringChrome Full support 38Edge Full support 12Firefox Full support 36IE No support NoOpera Full support 25Safari Full support 9WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 36Opera Android Full support 25Safari iOS Full support 9Samsung Internet Android Full support 3.0nodejs Full support 0.12
toStringTagChrome Full support 49Edge Full support 15Firefox Full support 51IE No support NoOpera Full support 36Safari Full support 10WebView Android Full support 49Chrome Android Full support 49Firefox Android Full support 51Opera Android Full support 36Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0
Full support 6.0.0
Full support 4.0.0
Disabled
Disabled From version 4.0.0: this feature is behind the --harmony runtime flag.
unscopablesChrome Full support 45Edge Full support 12Firefox Full support 48IE No support NoOpera Full support 32Safari Full support 9WebView Android Full support 45Chrome Android Full support 45Firefox Android Full support 48Opera Android Full support 32Safari iOS Full support 9Samsung Internet Android Full support 5.0nodejs Full support 0.12
valueOfChrome Full support 38Edge Full support 12Firefox Full support 36IE No support NoOpera Full support 25Safari Full support 9WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 36Opera Android Full support 25Safari iOS Full support 9Samsung Internet Android Full support 3.0nodejs Full support 0.12
@@toPrimitiveChrome Full support 47Edge Full support 15Firefox Full support 44IE No support NoOpera Full support 34Safari Full support 10WebView Android Full support 47Chrome Android Full support 47Firefox Android Full support 44Opera Android Full support 34Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0

Legend

Full support  
Full support
No support  
No support
Non-standard. Expect poor cross-browser support.
Non-standard. Expect poor cross-browser support.
See implementation notes.
See implementation notes.
User must explicitly enable this feature.
User must explicitly enable this feature.

See also