W3cubDocs

/JavaScript

Symbol

Symbol is a built-in object whose constructor returns a symbol primitive — also called a Symbol value or just a Symbol — that’s guaranteed to be unique. Symbols are often used to add unique property keys to an object that won’t collide with keys any other code might add to the object, and which are hidden from any mechanisms other code will typically use to access the object. That enables a form of weak encapsulation, or a weak form of information hiding.

Every Symbol() call is guaranteed to return a unique Symbol. Every Symbol.for("key") call will always return the same Symbol for a given value of "key". When Symbol.for("key") is called, if a Symbol with the given key can be found in the global Symbol registry, that Symbol is returned. Otherwise, a new Symbol is created, added to the global Symbol registry under the given key, and returned.

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. 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 Symbol. Overrides the Object.prototype.valueOf() method.

Symbol.prototype[@@toPrimitive]

Returns the Symbol.

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

Browser compatibility

Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari WebView Android Chrome Android Firefox for Android Opera Android Safari on IOS Samsung Internet Deno Node.js
Symbol
38
12
Edge 12 included Symbol properties in JSON.stringify() output.
36
No
25
9
38
38
36
25
9
3.0
1.0
0.12.0
Symbol
38
12
36
No
25
9
38
38
36
25
9
3.0
1.0
0.12.0
asyncIterator
63
79
57
No
50
11.1
63
63
57
46
No
8.0
1.0
10.0.0
description
70
79
63
No
57
12.1
12
No support for an undefined description.
70
70
63
49
12.2
12
No support for an undefined description.
10.0
1.0
11.0.0
for
40
12
36
No
27
9
40
40
36
27
9
4.0
1.0
0.12.0
hasInstance
50
15
50
No
37
10
50
50
50
37
10
5.0
1.0
6.5.0
6.0.0
isConcatSpreadable
48
15
48
No
35
10
48
48
48
35
10
5.0
1.0
6.0.0
iterator
43
12
36
No
30
10
43
43
36
30
10
4.0
1.0
0.12.0
keyFor
40
12
36
No
27
9
40
40
36
27
9
4.0
1.0
0.12.0
match
50
79
40
No
37
10
50
50
40
37
10
5.0
1.0
6.0.0
matchAll
73
79
67
No
60
13
73
73
67
52
13
11.0
1.0
12.0.0
replace
50
79
49
No
37
10
50
50
49
37
10
5.0
1.0
6.0.0
search
50
79
49
No
37
10
50
50
49
37
10
5.0
1.0
6.0.0
species
51
13
41
No
38
10
51
51
41
41
10
5.0
1.0
6.5.0
6.0.0
split
50
79
49
No
37
10
50
50
49
37
10
5.0
1.0
6.0.0
toPrimitive
47
15
44
No
34
10
47
47
44
34
10
5.0
1.0
6.0.0
toSource
No
No
36-74
Starting in Firefox 74, toSource() is no longer available for use by web content. It is still allowed for internal and privileged code.
No
No
No
No
No
36
No
No
No
No
No
toString
38
12
36
No
25
9
38
38
36
25
9
3.0
1.0
0.12.0
toStringTag
49
15
51
No
36
10
49
49
51
36
10
5.0
1.0
6.0.0
4.0.0
unscopables
45
12
48
No
32
9
45
45
48
32
9
5.0
1.0
0.12.0
valueOf
38
12
36
No
25
9
38
38
36
25
9
3.0
1.0
0.12.0
@@toPrimitive
47
15
44
No
34
10
47
47
44
34
10
5.0
1.0
6.0.0

See also

© 2005–2021 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol