Categories
Modern JavaScript

Best of Modern JavaScript — Symbols API

Spread the love

Since 2015, JavaScript has improved immensely.

It’s much more pleasant to use it now than ever.

In this article, we’ll look at JavaScript symbols.

Crossing Realms with Symbols

Symbols don’t travel well across realms.

Since there’re different global objects in different frames, we can’t use them across frames.

Special symbols like Symbol.iterator should work across different realms.

To get a symbol across different realms, we can use the Symbol.for method to get the symbol with a string.

For example, we can write:

const sym = Symbol.for('foo');

Then we can call Symbol.keyFor to get the string we passed into Symbol to create the symbol:

Symbol.keyFor(sym)

Special symbols like Symbol.iterator will return undefined if we call it with Symbol.keyFor :

Symbol.keyFor(Symbol.iterator)

Are Symbols Primitives or Objects?

Symbols are primitive values.

Symbols are like strings in that they can be used as property keys.

But they’re like objects in that each symbol has their own identity.

They’re immutable and they can be used as property keys.

However, it doesn’t have many properties of objects like prototypes and wrappers.

Symbol also can’t be examined by operators and methods like instance or Object.keys .

Why are Symbols Useful?

Symbols are useful for avoid clashes of identifiers.

This is easy since we can’t create the same symbol twice.

Are JavaScript Symbols Like Ruby’s Symbols?

JavaScript and Ruby symbols aren’t alike.

Ruby symbols are literals for creating values.

For instance, if we have:

`:foo` `==` `:foo`

then the expression returns true .

Symbol(‘foo’) !== Symbol(‘foo’) returns true .

So no 2 symbols are the same even though we passed in the same argument.

The Spelling of Well-Known Symbols

Well-known symbols are spelled this way because they’re used as normal property keys.

Symbol API

Symbol is a function that takes a string as its description.

So we can use it by writing:

const sym = Symbol('foo');

to get a new symbol.

Methods of Symbols

The only useful method in a symbol is the toString method.

Well-known Symbols

There’re several well-knowns that may be useful to us.

The Symbol.hasInstance method lets an object customize the behavior of the instanceof operator.

Symbol.toPrimitive is a method that lets us customize how it’s converted to a primitive value.

This is the 1st steep whenever something is being coerced into a primitive value.

Symbol.toStringTag is a method called by Object.prototype.toString to return the string description of an object.

Therefore, we can override it to provide our own string description.

Symbol.unscopables is a method that hides some properties with the with statement.

Symbol.iterator is a method that lets us define our own iterable to create an iterable object.

Once we added this method, we can iterate it with the for-of operator.

String Methods

String methods are forwarded to methods with the given symbols.

They’re forwarded as follows:

  • String.prototype.match(str, ...) is forwarded to str[Symbol.match]().
  • String.prototype.replace(str, ...) is forwarded to str[Symbol.replace]().
  • String.prototype.search(str, ...) is forwarded to str[Symbol.search](···).
  • String.prototype.split(str, ...) is forwarded to str[Symbol.split]().

Other Special Symbols

Symbol.species is a method to configure built-in methods to create objects similar to this .

Symbol.isConcatSpreadable is a boolean to configure whether Array.prototype.concat adds the indexed element as the result.

Conclusion

There’re many special symbols we can use to override the behavior of objects.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *