JS: Symbol Tutorial

By Xah Lee. Date: . Last updated: .

New in ES2015.

Symbol is a primitive type. 〔►see JS: Data Types

The Symbol type is the set of all non-string values that may be used as the key of a object property.

The purpose of symbol is to avoid property name collision.

Each possible symbol value is unique and immutable.

Each symbol value has an associated value called “Description”, usually denoted in document as [[Description]] that is either undefined or a value of string type. This [[Description]] cannot be changed.

Creating Symbol

Symbol() → creates a symbol.

Symbol(description) → creates a symbol with description string description. The description is a printed representation of the symbol, mostly for debugging purposes. By default, the description is a string "undefined". The description is used when you convert symbol to string. Note: 2 symbols with same description are still different symbols.

// creating symbol

const x = Symbol();
const y = Symbol();
const z = Symbol("my cat");

console.log(x); // prints Symbol()
console.log(y); // prints Symbol()
console.log(z); // prints Symbol(my cat)

typeof on symbol value returns string "symbol".

// typeof on symbol

let x = Symbol();
console.log( typeof x === "symbol" ); // true

let y = Symbol("abc");
console.log( typeof y === "symbol" ); // true

〔►see JS: Data Types

〔►see JS: const Declaration

「Symbol()」 Cannot be Used with 「new」

Symbol() cannot be used with new.

// Symbol() cannot be used as constructor
let x = new Symbol();
// TypeError: Symbol is not a constructor

Symbol() Returns a Unique Symbol, Always

// Symbol() always returns a unique symbol

let x = Symbol();
let y = Symbol();

console.log(x === y); // prints false

Using Symbol as Property Key

The symbol type is primarily designed to be keys for properties. Because symbol values are unique, this means property key collision cannot happen. Now you can add properties to objects in libraries or your own library and don't have to worry about property key collision.

Before ES2015, property key can only be string type. In ES2015, property key can be either a string type or symbol type.

Use bracket notation to access property symbol. For example, obj[variable_of_symbol] or obj[symbol_value].

// adding a property with symbol key, via a variable's value
let x = Symbol();
let obj = {};
obj[x] = 3;
console.log(obj[x]); // 3
// adding a property with symbol key, via symbol value directly
let obj = {};
obj[Symbol()] = 4;

) // 4

// getOwnPropertySymbols returns a array of symbol keys

Note: you cannot use dot notation for property keys that are symbol. 〔►see JS: Property Dot Notation / Bracket Notation

Computed Property Key

ES2015 extended object literal expression syntax to allow dynamically evaluated property key. Like this:

let obj = {[expression]:value}

This is especially useful for symbol key.

// es2016 computed property syntax. use [] around the property key
let aa = Symbol();
let obj = {[aa]:3};   // symbol
console.log(obj[aa]); // 3

〔►see JS: ES2015 Object Literal Expression Extensions

Symbol Properties Are Usually Ignored

Properties with symbol as key are usually ignored by constructs that access properties.

let x = Symbol();
let obj = {};
obj[x] = 4;

console.log(obj[x]); // 4, exists

// symbol key properties are ignored by many constructs
console.log(obj); // {}
console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertyNames(obj)); // []

for (let p in obj) { console.log(p); } // prints nothing

〔►see JS: Access Property, List Properties

Check If a Object Has Own Symbol Key

obj.hasOwnProperty(key) → return true if obj has own property key key (string or symbol) keys.

see JS: Check Property Existence

Check If a Object Has Symbol Key in Prototype Chain

To check if a property key is in a object obj's prototype chain (including if it's its own property), use one of:

see JS: Check Property Existence

〔►see JS: Reflect Object

Access Symbol Key Properties

If you have a variable that holds a symbol value, you can access it by bracket notation, like this: obj[var_of_symbol].

let x = Symbol("xyz");
let obj = {};
obj[x] = 4;

// bracket notation to access symbol property
console.log( obj[x] ); // 4


Object.getOwnPropertySymbols(obj) → return a array of symbol keys of obj.

// list symbol key properties of a object

let x = Symbol("xyz");
let obj = {};
obj[x] = 4;

); // prints [ Symbol(xyz) ]

〔►see JS: Object Object

ECMAScript 2015 §Fundamental Objects#sec-object.getownpropertysymbols


Reflect.ownKeys(obj) → return a array of all (string and symbol) property keys.

let obj = {};
obj["y"] = 3;
obj[Symbol("x")] = 4;

// list all properties of a object, string valued and symbol valued
); // prints [ 'y', Symbol(x) ]

〔►see JS: Reflect Object

ECMAScript 2015 §Reflection#sec-reflect.ownkeys

Convert Symbol to String

let s = Symbol("cat");

console.log("my " + s)
// TypeError: Cannot convert a Symbol value to a string
// convert symbol to string

let s = Symbol("cat");

console.log(s.toString()); // Symbol(cat)

// or
console.log(String(s)); // Symbol(cat)

Symbol Topic

  1. JS: Symbol Tutorial
  2. JS: Symbol Object
  3. JS: Symbol.prototype
Like what you read? Buy JavaScript in Depth