10-ES6++: Symbols

hassanzohdy

Hasan Zohdy

Posted on November 19, 2022

10-ES6++: Symbols

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.

const symbol = Symbol();
Enter fullscreen mode Exit fullscreen mode

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

const missingKey = Symbol("missingKey");
Enter fullscreen mode Exit fullscreen mode

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

const symbol1 = Symbol("symbol");

const symbol2 = Symbol("symbol");

console.log(symbol1 === symbol2); // false
Enter fullscreen mode Exit fullscreen mode

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.

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

console.log(person); // { name: 'Hasan', age: 30, city: 'Cairo' }
Enter fullscreen mode Exit fullscreen mode

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.


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
Enter fullscreen mode Exit fullscreen mode

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.

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
}
Enter fullscreen mode Exit fullscreen mode

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.

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
}
Enter fullscreen mode Exit fullscreen mode

Object async generators

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

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
  }
})();
Enter fullscreen mode Exit fullscreen mode

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.

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

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

console.log(symbol1 === symbol2); // true
Enter fullscreen mode Exit fullscreen mode

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.

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

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

console.log(key); // MySymbolKey
Enter fullscreen mode Exit fullscreen mode

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

const symbol1 = Symbol("MySymbolKey");

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

console.log(key); // undefined
Enter fullscreen mode Exit fullscreen mode

🎨 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, it will help me to keep going and keep creating more content.

😍 Join our community

Join our community on Discord 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

Packages & Libraries

React Js Packages

Courses (Articles)

💖 💪 🙅 🚩
hassanzohdy
Hasan Zohdy

Posted on November 19, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

16-ES6++: Reflection In JavaScript
javascript 16-ES6++: Reflection In JavaScript

December 6, 2022

15-ES6++: Proxy In JavaScript
javascript 15-ES6++: Proxy In JavaScript

December 4, 2022

14-ES6++: Null Coalescing in Javascript
javascript 14-ES6++: Null Coalescing in Javascript

November 26, 2022

13-ES6++: Optional Chaining in Javascript
javascript 13-ES6++: Optional Chaining in Javascript

November 26, 2022