10-ES6++: Symbols
Tags: javascript, es6, esnext
Published: 2022-11-19 11:47:18

---
title: 10-ES6++: Symbols
published: true
description: 
series: es6++
tags: javascript, es6, esnext
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ofs0ukxtf3e8mmdxrpe.png
# Use a ratio of 100:42 for best results.
# published_at: 2022-10-25 09:51 +0000
---

## Symbols

In **ES6** we have a new primitive data type called `symbol`. Symbols are used to create `unique identifiers` for objects. We can also use symbols to create private properties and methods in objects, but let's first see how to create symbols.

### Creating symbols

To create a symbol, we use the `Symbol()` function.

```js
const symbol = Symbol();
```

The `Symbol()` function can take an optional `description` parameter, which is used to describe the symbol.

```js
const missingKey = Symbol("missingKey");
```

The `description` parameter is used to describe the symbol, it's not used to set the value of the symbol.

## Uniqueness of symbols

In that sense, we can conclude that every symbol is unique, even if they have the same description.

Let's see an example

```js
const symbol1 = Symbol("symbol");

const symbol2 = Symbol("symbol");

console.log(symbol1 === symbol2); // false
```

Same exact description but they are different, how is that possible? let me explain.

Each time the `Symbol` function is called (`BTW it can not be instantiated with new keyword, you can not do new Symbol`), it returns a new symbol, that symbol is guaranteed to be unique `during`, it is stored in a `global symbol registry` to make sure it's unique.

## When to use symbols

Symbols have really really useful use cases, they can be used in:

* Object Properties
* Object methods
* Object iterators
* Object generators
* Object async generators

Let's see an example for each use case of the above list.

### Object Properties

We can use symbols to create private properties in objects.

```js
const person = {
  name: "Hasan",
  age: 30,
  city: "Cairo",
  [Symbol("secret")]: "MySecret",
};

console.log(person); // { name: 'Hasan', age: 30, city: 'Cairo' }
```

As you can see, the `secret` property is not visible in the console, because it's a private property.

### Object methods

We can also use symbols to create private methods in objects.

```js

const isAdult = Symbol("isAdult");

const person = {
  name: "Hasan",
  age: 30,
  city: "Cairo",
  [isAdult]() {
    return this.age >= 18;
  },
  canVote() {
    if (this[isAdult]()) {
      console.log("You can vote");
    } else {
      console.log("You can not vote");
    }
  },
};

person.canVote(); // You can vote
```

So we've here created some sort of a `private` method called `isAdult`, and we used it in the `canVote` method, this will make sure that this method is not accessible from outside the object.

### Object iterators

We can also use symbols to create iterators for objects.

```js
const person = {
  name: "Hasan",
  age: 30,
  city: "Cairo",
  // iterate and return key, value pairs
  [Symbol.iterator]() {
    const keys = Object.keys(this);
    let index = 0;
    return {
      next: () => {
        if (index < keys.length) {
          const key = keys[index];
          const value = this[key];
          index++;
          return {
            value: [key, value],
            done: false,
          };
        } else {
          return {
            done: true,
          };
        }
      },
    };
  },
};

for (const [key, value] of person) {
  console.log(key, value); // name Hasan age 30 city Cairo
}
```

That one of the most important ways to use in your class/object to perform iteration over it.

### Object generators

We can also use symbols to create generators for objects.

```js
const person = {
  name: "Hasan",
  age: 30,
  city: "Cairo",
  // iterate and return key, value pairs
  *[Symbol.iterator]() {
    const keys = Object.keys(this);
    for (const key of keys) {
      yield [key, this[key]];
    }
  },
};

for (const [key, value] of person) {
  console.log(key, value); // name Hasan age 30 city Cairo
}
```

### Object async generators

We can also use symbols to create async generators for objects.

```js
const person = {
  name: "Hasan",
  age: 30,
  city: "Cairo",
  // iterate and return key, value pairs
  async *[Symbol.asyncIterator]() {
    const keys = Object.keys(this);
    for (const key of keys) {
      yield [key, this[key]];
    }
  },
};

(async () => {
  for await (const [key, value] of person) {
    console.log(key, value); // name Hasan age 30 city Cairo
  }
})();
```

## Symbol.for()

The `Symbol.for(key)` method searches for existing symbols in the symbol registry with the given key and returns it if found. Otherwise a new symbol gets created in the global symbol registry with this key.

```js
const symbol1 = Symbol.for("symbol");

const symbol2 = Symbol.for("symbol");

console.log(symbol1 === symbol2); // true
```

As you can see, the symbols are the same, because they are stored in the global symbol registry.

So if we want to control the value of a symbol, we should use `Symbol.for()`, but it is **`not recommended`** to use it most of the time, because it can cause some problems.

## Symbol.keyFor()

The `Symbol.keyFor(symbol)` method returns a shared symbol key from the global symbol registry for the given symbol.

```js
const symbol1 = Symbol.for("MySymbolKey");

// now using keyFor method
const key = Symbol.keyFor(symbol1); 

console.log(key); // MySymbolKey
```

This won't work with does not have a key, it will return undefined if you used it with `Symbol` function for example.

```js
const symbol1 = Symbol("MySymbolKey");

// now using keyFor method
const key = Symbol.keyFor(symbol1); 

console.log(key); // undefined
```

## 🎨 Conclusion

In this article, we've learned about symbols, how to create them, how to manually set symbol key and how to retrieve that key, and how to use them properly.

## ☕♨️ Buy me a Coffee ♨️☕

If you enjoy my articles and see it useful to you, you may [buy me a coffee](https://www.paypal.com/paypalme/hassanzohdy), it will help me to keep going and keep creating more content.

## 😍 Join our community

Join our community on [Discord](https://discord.gg/pb2vmdfhGf) to get help and support (Node Js 2023 Channel).

## 📚 Bonus Content 📚

You may have a look at these articles, it will definitely boost your knowledge and productivity.

General Topics

* [Event Driven Architecture: A Practical Guide in Javascript](https://dev.to/hassanzohdy/event-driven-architecture-the-best-paradigm-that-i-love-to-work-with-in-javascript-and-node-js-1gnk)
* [Best Practices For Case Styles: Camel, Pascal, Snake, and Kebab Case In Node And Javascript](https://dev.to/hassanzohdy/best-practices-for-case-styles-camel-pascal-snake-and-kebab-case-in-node-and-javascript-55oi)
* [After 6 years of practicing MongoDB, Here are my thoughts on MongoDB vs MySQL
](https://dev.to/hassanzohdy/after-6-years-of-practicing-mongodb-here-are-my-thoughts-on-mongodb-vs-mysql-574b)

Packages & Libraries

* [Collections: Your ultimate Javascript Arrays Manager](https://dev.to/hassanzohdy/collections-your-ultimate-javascript-array-handler-3o15)
* [Supportive Is: an elegant utility to check types of values in JavaScript](https://dev.to/hassanzohdy/supportive-is-an-elegant-utility-to-check-types-of-values-in-javascript-1b3e)
* [Localization: An agnostic i18n package to manage localization in your project](https://dev.to/hassanzohdy/mongez-localization-the-simplest-way-to-translate-your-website-regardless-your-favorite-framework-4gi3)

 React Js Packages

* [useFetcher: easiest way to fetch data in React Js](https://dev.to/hassanzohdy/usefetcher-the-easiest-way-to-fetch-data-in-react-45o9)

Courses (Articles)

* [Node Js 2023 Course: Node With Typescript, The Ultimate Guide](https://dev.to/hassanzohdy/nodejs-course-2023-introduction-to-nodejs-3n4e)
* [React Js: Let"s Create File Manager With React Js and Node Js](https://dev.to/hassanzohdy/lets-create-a-file-manager-from-scratch-with-react-and-typescript-chapter-i-a-good-way-to-expand-your-experience-5g4k)