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.
Decorators have become popular thanks to their use in Angular 2+. In Angular, decorators are available thanks to TypeScript, but in JavaScript they’re 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.
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’s possible to use as many decorators on the same piece of code as you desire, and they’ll 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 callsObject.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’re 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 Babel 5 way of handling decorators, which might well be different from the final form when they’re standardized.
Why Use Decorators?
Whilst functional composition is already possible in JavaScript, it’s 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’re writing.
Continue reading %JavaScript Decorators: What They Are and When to Use Them%
LEAVE A REPLY
You must be logged in to post a comment.