JavaScript Decorators: What They Are and When to Use Them

With the introduction of ES2015+, and as transpilation has become commonplace, many of you will have come across newer language features, either in real code or tutorials. One of these features that often has people scratching their heads when they first come across them are JavaScript decorators.

Editor’s Note: This article has been updated in response to reader comments to remove the incorrect claim that decorators were part of the forthcoming ES2017 standard.

Decorators have become popular thanks to their use in Angular 2+. In Angular, decorators are available thanks to TypeScript, but in JavaScript they are currently a stage 2 proposal, meaning they should be part of a future update to the language . Let’s take a look at what decorators are, and how they can be used to make your code cleaner and more easily understandable.

Note: If you’re more of a video person, why not sign up for SitePoint Premium and check out some of our popular JavaScript courses?

What is a Decorator?

In its simplest form, a decorator is simply a way of wrapping one piece of code with another – literally “decorating” it.
This is a concept you might well have heard of previously as “Functional Composition”, or “Higher-Order Functions”.

This is already possible in standard JavaScript for many use cases, simply by calling on one function to wrap another:

function doSomething(name) {
  console.log('Hello, ' + name);
}

function loggingDecorator(wrapped) {
  return function() {
    console.log('Starting');
    const result = wrapped.apply(this, arguments);
    console.log('Finished');
    return result;
  }
}

const wrapped = loggingDecorator(doSomething);

This example produces a new function – in the variable wrapped – that can be called exactly the same way as the doSomething function, and will do exactly the same thing. The difference is that it will do some logging before and after the wrapped function is called.

doSomething('Graham');
// Hello, Graham
wrapped('Graham');
// Starting
// Hello, Graham
// Finished

How to use JavaScript Decorators?

Decorators use a special syntax in JavaScript, whereby they are prefixed with an @ symbol and placed immediately before the code being decorated.

Note: At the time of writing, the decorators are currently in “Stage 2 Draft” form, meaning that they are mostly finished but still subject to changes.

It is possible to use as many decorators on the same piece of code as you desire, and they will be applied in the order that you declare them.

For example:

@log()
@immutable()
class Example {
  @time('demo')
  doSomething() {

  }
}

This defines a class and applies three decorators: two to the class itself and one to a property of the class:

  • @log could log all access to the class.
  • @immutable could make the class immutable – maybe it calls Object.freeze on new instances.
  • @time will record how long a method takes to execute and log this out with a unique tag.

At present, using decorators requires transpiler support, since no current browser or Node release has support for them yet.
If you are using Babel, this is enabled simply by using the transform-decorators-legacy plugin.

Note: the use of the word “legacy” in this Plugin is because it supports the way that Babel 5 handled Decorators, which might well be different to the final form when they are standardized.

Why use Decorators?

Whilst functional composition is already possible in JavaScript, it is significantly more difficult – or even impossible – to apply the same techniques to other pieces of code (e.g. classes and class properties).

The decorator proposal adds support for class and property decorators that can be used to resolve these issues, and future JavaScript versions will probably add decorator support for other troublesome areas of code.

Decorators also allow for a cleaner syntax for applying these wrappers around your code, resulting in something that detracts less from the actual intention of what you are writing.

Different Types of Decorator

At present, the only types of decorator that are supported are on classes and members of classes. This includes properties, methods, getters, and setters.

Decorators are actually nothing more than functions that return another function, and that are called with the appropriate details of the item being decorated. These decorator functions are evaluated once when the program first runs, and the decorated code is replaced with the return value.

Continue reading %JavaScript Decorators: What They Are and When to Use Them%


Source: Sitepoint