JavaScript Decorators

It’s no secret that programming languages will implement features from other programming languages when it’s a smart solution for a problem (did I just hear you say async/await?) or if the feature is really useful and generally nice to have.
That is why today we’ll be talking about decorators, how they fit in JavaScript and we’ll be going over a simple example.

Decorators are currently a stage 2 proposal which means they’re still not in JavaScript but probably will be in the future.

While decorators don’t solely exist in Python we’ll be looking at their definitions and explanations since JavaScript decorators will (probably) look a lot like Python decorators. (It also helps that I’m a huge fan of Python and think it’s the most baller programming language after JavaScript).

What is the decorator pattern?

In object-oriented programming, the decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern.
Definition taken from Wikipedia. (Link)

So what does Python say decorators are?

A decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it.
Definition taken from Primer on Python Decorators. (Link)

The gist of it

Decorators take one thingy and make it better by adding logic from another thingy.

Apologies for the scientific terminology, sometimes you just can’t get around using it…

This is what decorators look like written in Python:
Example taken from Wikipedia. (Link)

def viking_chorus(myfunc):
def inner_func(*args, **kwargs):
for i in range(8):
myfunc(*args, **kwargs)
return inner_func
@viking_chorus
def menu_item():
print("spam")

Don’t think too much about the code if you’re not into Python. The only interesting part up there for us is the ‘@viking_chorus’
The above code translates to:

def menu_item():
print("spam")
menu_item = viking_chorus(menu_item)

As you can see the decorator is basically just a cool kid’s way of calling higher-order functions, which is beyond easy in JavaScript, although if not used correctly can get quite ugly.
JavaScript isn’t trying to tackle this non-problem instead it’s setting its sights on something else — classes and class members (properties). 
Imagine you have multiple classes that need to share the same chunk of functionality or in multiple classes you need to modify certain properties the same way. 
Inheritance is nice but it can only get you so far, in these cases the usefulness of decorators becomes apparent.

Lets look at a really simple example of a JavaScript decorator, one you’ll most likely find floating on the internet — a class member decorator that modifies a class property.

function readonly(target, name, descriptor) {
descriptor.writable = false;
return descriptor;
}
class Job {
@readonly
title() { return 'CEO' }
}

What the code above does is modify the ‘title’ property so it can’t be reassigned, making it ‘readonly’

See how I named the decorator ‘readonly’ and it modifies properties so that you can only read them? That’s years of software development experience right there, baby!

You’re probably wondering what are all those function arguments, so lets go over them:

target — class that the property is a part of
name — the name of the property the decorator is modifying
descriptor — property descriptor. Think: object passed to Object.defineProperty

From the example above we can see that not only do decorators make the code cleaner but also sharing bits of common logic across class properties becomes incredibly easy.

Which is the whole point of decorators.

Angular 2

I’m mentioning Angular 2 here because Angular 2 uses Typescript, Typescript supports decorators and they’re used heavily in Angular 2.
I’ve been working on an Angular 2 project for a while now and kinda stopped noticing decorators, they just become mundane but when you start noticing them again you see how much nicer the code is because of them.

Lets look at how you create a component class and decorate it in Angular 2

@Component({
selector: 'example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent { ... }

That’s a really cool way of adding metadata to a component class.
‘Selector’ is the html tag angular will use to render this component (<example></example>)
‘templateUrl’ is the html for this component
‘styleUrls’ is a list of css styles the component will use

‘@Component’ is a great example of sharing common functionality between classes.
Something that would’ve been a royal pain in the ass without decorators is cleanly and simply handled with decorators. Nice!

React

React is a prime candidate to start using decorators since its higher-order components are higher-order functions that return components.
In fact, decorators are such a good fit with React that react-dnd, the most popular React drag and drop library, is already using them! ( Link )

Takeaway

JavaScript decorators are still not officially supported but they’re going to be soon and developers that take the time to study up on them will be in a much better position than the ones who don’t.
My advice is to check out how they’re used in other languages because that’s probably how you’ll be using them in JavaScript, maybe even experiment and create your own decorators that abstract away common shared class or class property logic!