DEV Community

Cover image for JavaScript Symbol
Bello Osagie
Bello Osagie

Posted on • Edited on

JavaScript Symbol

In JavaScript, the object key can only be in either string or symbol.

A symbol represents a unique identifier

To create a symbol, the syntax is shown below:

id = Symbol()
Enter fullscreen mode Exit fullscreen mode

To create a symbol with a description (symbol-name), the syntax is shown below:

id = Symbol("description")
Enter fullscreen mode Exit fullscreen mode

The description is just a label that is unique to an object.

It is important to note that symbols with the same description are still different.

See the example below:

const id1 = Symbol("description");
const id2 = Symbol("description");

console.log(id1 === id2); // false
Enter fullscreen mode Exit fullscreen mode

It is also important to note that symbols do not allow auto-conversion (coercion) to string.

See the example below:

const id3 = Symbol("description");
alert(id3); // TypeError...
Enter fullscreen mode Exit fullscreen mode

To do the conversion, use the toString() function on it.

See the example below:

const id4 = Symbol("id");
alert(typeof id4.toString); // string
Enter fullscreen mode Exit fullscreen mode

Alternatively, we can use the id.description to show the description only.

let id5 = Symbol("id");
alert(id5.description, toString id5.description); // id string
Enter fullscreen mode Exit fullscreen mode

Hidden Properties

Symbols allow us to create hidden properties of an object.
See the example below:

const person = { // belongs to another code
  name: "Bello"
};

let id = Symbol("id");

person[id] = 4; // added id key to user object

alert( person[id] ); // 4 => accessed data by the symbol as the key
Enter fullscreen mode Exit fullscreen mode

The code above shows that a symbol cannot be accessed accidentally by any part of your code.

If a string is used in place of a symbol, the last string "id" will be overridden (overwritten) by any other previous string id from our script or another JavaScript library script.

See the example below:

const person = { name: "John" };

// my script uses "id" property
person.id = "id value before the last script";

// library script uses the "id" property
person.id = "id value in last script" // overwritten by another script!
console.log(person.id); // id value in last script
Enter fullscreen mode Exit fullscreen mode

Symbol id as key

To use a symbol as a key in an object literal, the square bracket must be used around it.

const id = Symbol("id");

const user = {
  name: "John",
  [id]: 639 // not "id": 639
};
Enter fullscreen mode Exit fullscreen mode

Cloning symbol keys

The for...in skips any symbol key in an object.
See the example below:

const id = Symbol("id");
const user = {
  name: "Bello",
  age: 27,
  [id]: 396
};

for (let key in user) {
  console.log(key); // name, age => no symbols
}
// Object.keys(user) also skips them.
Enter fullscreen mode Exit fullscreen mode

The Object.assign copies both string and symbol properties.

See the example below:

const id = Symbol("id");
const user = {
  name: "Bello",
  age: 27,
  [id]: 396
};

let clone = Object.assign({}, user);
alert( clone[id] ); // 396
Enter fullscreen mode Exit fullscreen mode

Global Symbol Registry

Symbols are always different by default even if they have the same description, but sometimes we want to use the same-named symbol of the same entities anyway in a program.

To achieve that, the Symbol.for(key) is used to create a global symbol registry for repeated access by the same name to return exactly the same symbol.

See the example below:

const id1 = Symbol.for("id"); // if the symbol did not exist, it is created
const id2 = Symbol.for("id");

console.log( id1 === id2); // true => the same symbol
Enter fullscreen mode Exit fullscreen mode

Symbols inside the registry are called global symbols.


Symbol.keyFor

The reverse of Symbol.for is Symbol.keyFor, it returns a name by a global symbol.

See the example below:

// get symbol by name
const sym1 = Symbol.for("id1");
const sym2 = Symbol.for("id2");

// get name by symbol
console.log( Symbol.keyFor(sym1) ); // id1
console.log( Symbol.keyFor(sym2) ); // id2
Enter fullscreen mode Exit fullscreen mode

The Symbol.keyFor internally uses the global symbol registry to look up the key for the symbol. If the symbol is not global, it returns undefined

See the example below:

const globalSymbol = Symbol.for("globalName");
const localSymbol = Symbol("localName");

console.log( Symbol.keyFor(globalSymbol) ); // globalName => global symbol
console.log( Symbol.keyFor(localSymbol) ); // undefined => not global

console.log( localSymbol.description ); // localName
Enter fullscreen mode Exit fullscreen mode

System Symbols

Internally, there are different JavaScript System Symbols.
Below is a few of them.

  • Symbol.hasInstance
  • Symbol.isConcatSpreadable
  • Symbol.iterator
  • Symbol.toPrimitive

Check out the full list on MDN`

Top comments (0)