DEV Community

Charlie @ 90-10.dev
Charlie @ 90-10.dev

Posted on • Originally published at 90-10.dev on

JavaScript Symbols

A symbol is a unique and immutable data type that represents an identifier.

Symbols was first introduced in ECMAScript 6 , and they are used to define properties of an object that cannot be accessed or modified by other parts of the code.

Creating Symbols

Declaring a symbol doesn't require the new keyword:

let mySymbol = Symbol();
Enter fullscreen mode Exit fullscreen mode

We can also provide a string when creating a symbol; it acts as a label for the symbol and can help with debugging.

let anotherSymbol = Symbol('test2');
Enter fullscreen mode Exit fullscreen mode

Uniqueness

Symbols are unique, even when providing a string for them:

Symbol('a') === Symbol('a') // returns: false
Enter fullscreen mode Exit fullscreen mode

Define Constants

Symbols can also be used to define constants by using them as property keys, ensuring that the property cannot be accidentally modified or deleted.

const THE_CONSTANT = Symbol();
const theAnswer = {

};
console.log(theAnswer[THE_CONSTANT]); // prints: 42

theAnswer[THE_CONSTANT] = 3.14;
console.log(theAnswer[THE_CONSTANT]); // prints: 42

delete theAnswer[THE_CONSTANT];
console.log(theAnswer[THE_CONSTANT]); // prints: 42
Enter fullscreen mode Exit fullscreen mode

Hide Information

Symbols can be used to hide information:

let mySymbol = Symbol('answer');
let obj = {
  x: 24,

}
console.log(obj.x); // prints: 24
console.log(obj.mySymbol); // prints: undefined
console.log(obj[mySymbol]); // prints: 42

mySymbol.toString() // prints: "Symbol(answer)"
Enter fullscreen mode Exit fullscreen mode

One would need to keep mySymbol variable around in order to access the second obj property.

let obj = {
    x: 24,

}

console.log(obj[Symbol("answer")]); // prints: undefined

Enter fullscreen mode Exit fullscreen mode

Private methods

Symbols can also be used to create complex internal logic that can't be accessed from outside the object:

const obj = {
  [Symbol.for('sum')]: function(x, y) {
    return x + y;
  },
  add: function(x, y) {
    return this[Symbol.for('sum')](x, y);
  }
};
console.log(obj.add(2, 3)); // prints: 5
console.log(obj.sum(2, 3)); // TypeError: obj.sum is not a function
Enter fullscreen mode Exit fullscreen mode

Notice the use of Symbol.for to retrieve a symbol from the global symbol registry.

Global Symbol Registry

The global symbol registry is a "concept" that might not be how actually it is implemented by JS engines but it's useful for the understanding how Symbol.for and Symbol.keyFor are used to retrieve symbols and keys across different files or global scopes.

// returns: false
Symbol('sum') === Symbol('sum')  

// returns: true
Symbol.for('sum') === Symbol.for('sum')  

Symbol.keyFor(Symbol.for("sum")) === "sum"
Enter fullscreen mode Exit fullscreen mode

Reading List

Top comments (0)