JavaScript

JavaScript Symbol Primitive Type | Explained

A new primitive type is introduced in ES6 known as “Symbol“. Symbols are built-in objects used to add unique property keys for a JavaScript object. These unique property keys won’t conflict with the keys added by other scripts and are hidden from the mechanisms used for accessing the object, such as “for..in” loop.

The JavaScript Symbol primitive type is created and can be shared globally. Moreover it can also be used to define the hidden properties of an object. There also exist some well-known JavaScript symbols that contain the common behavior of JavaScript.

This write-up will explain JavaScript Symbol Primitive Type with the help of suitable examples. So, let’s start!

How to create a Symbol primitive type in JavaScript

The global “Symbol()” function is utilized to create a new JavaScript symbol in the following way:

let regID = Symbol();

Here, “regID” is a new JavaScript Symbol primitive type.

You can also add the symbol description within the parenthesis “()” of the Symbol() function. This description is considered useful for debugging purposes and it also makes symbols more descriptive:

let regID = Symbol('Registration ID');

console.log(regID);

The output of the given code will display the primitive type of “regID” and its description:

Example: How to Create a Symbol primitive type in JavaScript

In the below-example, we will create two symbols named “name” and “age” and pass their descriptions as an argument to the “Symbol()” global function:

let name = Symbol('Employee name'),

age = Symbol('Age');

console.log(name);

console.log(age);

Execution of the above-given example shows the following output:

Now, we will use the JavaScript “typeof” operator to determine whether “name” and “age” variables are created as a symbol or not:

console.log(typeof name);

console.log(typeof age);

As you can see from the output, the “typeof” operator returned “symbol” as the type of the specified variables:

Remember that symbols are only created with the help of the “Symbol()” global function. For the same purpose, using the “new” operator will throw an error as Symbols are primitive values:

let regID = new Symbol();

regID” symbol will not be created, and the following “TypeError” will be shown:

The previous section provided the method for creating symbols as primitive type values. Now, we will move ahead and discuss how you can share symbols in JavaScript.

How to share a Symbol primitive type in JavaScript

The “Global Symbol Registry” supported by the ES6 permits you to share the created symbol globally by utilize the “Symbol.for()” method instead of using the “Symbol()” function.

For instance, we are creating a “regID” symbol with a description using “Symbol.for()” method:

let regID= Symbol.for('regID');

When the “Symbol.for()” method executes, it searches for the “regID” key in the Global Symbol Registry; if the “regID” symbol already exists in the registry, the “Symbol.for()” method will return it. In another case, a new “regID” symbol will be created and added to the Global Symbol Registry.

Now, invoking the “Symbol.for()” method while passing “regID” key as argument will return the existing “regID” symbol contained in the Global Symbol Registry:

let studentID = Symbol.for('regID');

console.log(regID === studentID);

The output shows “true” for the strict comparison between “regID” and “studentID” because both are the same in terms of type and added keys:

For the verification of the key associated with the “studentID”, we will execute the “keyFor()” method and pass the “studentID” as an argument:

console.log(Symbol.keyFor(studentID));

The “keyFor()” method will return “regID” as the studentID symbol’s key:

If you are searching for a symbol that is not added in the Global Symbol Registry, then the “keyFor()” method will return “undefined” value for the specified value:

let employeeID = Symbol('employeeID');

console.log(Symbol.keyFor(employeeID));

Here, the “employeeID” symbol does not exist in the Global Symbol Registry, because it is created using the “Symbol()” instead of “Symbol.for()” method, and when the “Symbol.for()” method looks for it in the Global Symbol Registry, it returned “undefined”:

You have seen that creating and sharing symbol primitive values is pretty straightforward. The following section will demonstrate how you can use these symbols in your JavaScript code.

How to use Symbols for creating hidden properties of an object in JavaScript

The JavaScript Symbol primitive value permits you to create hidden properties of an object. For this purpose, you can create a “symbol” and utilize it as an object’s property key. The created property will be skipped by the for..in loop, and another script would not be able to access it directly because the “symbol” is not included in other scripts. In this way, symbols are considered ideal for hiding object properties.

Example: How to use Symbols for creating hidden properties of an object in JavaScript

First of all, we will create an “articleStatus” object which comprises the following three symbols as its hidden properties:

let articleStatus = {

IN_PROGRESS: Symbol('Article In progress'),

COMPLETED: Symbol('Article Completed'),

FINALIZED: Symbol('Article Finalized'),

};

In the next step, we will add another symbol named “myStatus”:

let myStatus = Symbol('myStatus');

Here comes the exciting part, in the “task” object, we will add two properties, one is “description,” and the other is “[myStatus]”. “[myStatus]” is a computed property of the task object as it is derived from the “myStatus” symbol and its value comprises the “COMPLETED” hidden property of the “articleStatus” object:

let task = {

[myStatus]: articleStatus.COMPLETED,

description: ' JavaScript Symbol Primitive type'

};

console.log(task);

Output

The above-given output signifies that symbols work perfectly for creating hidden properties which can be only accessed with their associated objects.

Well-known Symbols in JavaScript

ES6 supports many predefined symbols that contain JavaScript’s common behavior, known as “well-known” symbols. These well-known symbols represent the static property of the “Symbol” object.

Let’s check out the most useful well-known Symbols of JavaScript.

Symbol.hasInstance in JavaScript

Symbol.hasInstance is a symbol that is used to determine if the constructor object identifies the specified object as its instance or not.

Syntax of Symbol.hasInstance in JavaScript

[Symbol.hasInstance](Object)

Here, the “Symbol.hasInstance” symbol accepts an “object” as an argument.

Example: Symbol.hasInstance in JavaScript

Typically, when an instanceof operator is used as “object instanceof type“, JavaScript invokes the “Symbol.hasInstance” symbol. Then, it verifies if the “object” is an instance of the other specified “type” object or not.

In the following example, the array “[ ]” is not an instance of the “Book” class, so the “instanceof” operator will return “false” as output:

class Book {

}

console.log([] instanceof Book);

Output

You can add the “Symbol.hasInstance” symbol to define array “[ ]” as an instance of the “Book” Class:

class Book {

static [Symbol.hasInstance](obj) {

return Array.isArray(obj);

}

}

console.log([] instanceof Book);

Output

Hence, the “instanceof” operator returned “true” after performing the specified check on the array “[ ]”.

Symbol.isConcatSpreadable in JavaScript

The Symbol.isConcatSpreadable Symbol returns a boolean value that determines whether a specified object is individually added to the result of the “concat()” function or not.

Syntax of Symbol.isConcatSpreadable in JavaScript

[Symbol.isConcatSpreadable]: value

Here, “value” is used to set the “boolean” value of Symbol.isConcatSpreadable symbol, where “true” permits the symbol to individually add the object elements and “false” will concatenate the specified object as a whole.

Example: Symbol.isConcatSpreadable in JavaScript

Firstly, we will create an “obj1” JavaScript, which has the following properties:

let obj1 = {

0: 'JS',

1: 'Symbol Primitive Type',

length: 2

};

In the next step, we will concatenate “obj1” with [‘Teaching’] array using the “concat()” function:

let info = ['Teaching'].concat(obj1);

console.log(info);

The concat() function will not spread the individual elements of “obj1” while concatenating it with [‘Teaching’] array:

If you want to individually add the elements of “obj1” to the array, you have to add the Symbol.isConcatSpreadable Symbol as a property to “obj1” and set its value to “true”:

let obj1 = {

0: 'JS',

1: 'Symbol Primitive Type',

length: 2,

[Symbol.isConcatSpreadable]: true

};

let info = ['Teaching'].concat(obj1);

console.log(info);

Check out the below-given output; the “obj1” elements are added individually in the resultant “info” array:

We have compiled all of the essential information related to the JavaScript Symbol Primitive Type.

Conclusion

Using the Symbol() global function, you can create a JavaScript symbol primitive type that contains a unique value, whereas the Symbol.for() method enables you to create a symbol that can be shared globally. JavaScript symbol primitive type is mostly used to define an object’s hidden properties. This write-up explained JavaScript Symbol Primitive Type with the help of suitable examples.

About the author

Sharqa Hameed

I am a Linux enthusiast, I love to read Every Linux blog on the internet. I hold masters degree in computer science and am passionate about learning and teaching.