Implementation and Usage of Decorators in Javascript
If you ever work with programming languages like Python and C# then you might be familiar with the function and purpose of Decorator.
If you haven’t then in this post I’ll teach you how you can use decorators in Javascript.
What are Decorators?
In the simplest definition, decorators are basically performing additional operations on classes. Unlike python where decorators can be used for both functions and classes, Here is Javascript Decorators are only be used on top of the Class.
Note
The decorator feature is still in the experimental phase and has not yet been released. These changes may be implemented in the near future as they make add more features.
Syntax to create a Decorator
function decorator_func( target ){ } @decorator_func class Test{ }
The function decorator_func
specified as decorator by adding @decorator_func
over the class Test
.
The function decorator_func
called when the file is loaded in memory.
Implementing decorator functionality without using a decorator
There are different ways you can implement the functionality of decorators in your existing projects. Some of them are listed below.
Using Function as Decorator
function mark_student_as_passout( obj ){ obj.is_passout = true return obj } function student( name, reg_no ){ return { name : name, reg_no : reg_no, } } let student_info = mark_student_as_passout( student( 'ram', 1 ) ) console.log(`student_info`, student_info) // op student_info {name: 'ram', reg_no: 1, is_passout: true}
Here the function mark_student_as_passout
acts as a decorator. But in the current case, it is just a simple function with receives an object and adds a property to it.
The function student( name, reg_no )
takes two arguments name
and reg_no
and returns an object. This object is then passed within mark_student_as_passout
function with the added property is_passout
to the object.
Using Higher-Order Functions
function print_func( func ){ return function( ){ return `${func()} Javascript` } } function say_hello(){ return "Hello" } var str = print_func( say_hello ) console.log(str()) //Hello Javascript
The working of higher-order functions is similar to the working of a decorator as they take a function as a parameter and return another function..
Here the function print_func
with is Higher-Order Function and returns another function. The output from print_func
is assigned to a variable str
.
So the variable also becomes a function object and can be called just a function.
Why use decorators in Javascript
In the current state of Javascript, we already have a solution to use higher-order functions instead of decorators. But the problem with higher-order functions is that they can only be used on functions and cannot be used on class or class methods.
In the future when we receive support for decorators then the implementation will become easier for using it in classes and methods.
How to run the javascript code which is using decorators
Currently, no browser supports decorators, and anyhow if you would like to explore its functionality and learn more about it then I recommend you visit jsfiddle.net and on top you see the select box choose language as Babel+JSX. By doing this you will be able to use decorators.
And there is also a plugin available to use it in your project as the Babel Legacy Decorator plugin.

How to run the javascript code which is using decorators
Types of Decorators
The decorators can be of two types class base decorator and class method base decorator. Below are both of those are elaborated.
Class-based Decorator
function work_timmings( _class ){ _class.working_hours = "10 am to 6 pm"; } @work_timmings class Employee{ } console.dir(Employee.working_hours) //10am to 6 pm
Suppose you want to specify work timing and instead of creating a new property within the class Employee
. Just create a decorator work_timmings
and add attribute working_hours
to the class.
To print or access its value simply call Employee.working_hours
.
Class Method Decorators
function work_timmings( ){ return function( target ){ target.working_hours = '10am to 6 pm' } } function immutable( target, key, descriptor ){ descriptor.writable = false return descriptor } @work_timmings( ) class Employee{ constructor( name, salary ){ this.name = name this.salary = salary } @immutable set_salary( salary ){ this.salary = salary } } let emp1 = new Employee("Sam", 50000) emp1.set_salary = function( salary ){ this.salary = 0 } emp1.set_salary( 500 ) console.log(emp1.salary) // 500
Javascript class methods can easily be overridden outside the class Employee.set_salary = function(){ return 0}
and to prevent this I have declared a decorator function which is immutable
.
The class method decorators take three parameters
- target: Which is the name of the class.
- key: Which is the method name.
- descriptor: Consist of a prototype of the method
Passing multiple parameters with the decorator
function work_timmings( value ){ return function( target ){ target.working_hours = value } } @work_timmings( '9am to 5 pm' ) class Employee{ } console.log(Employee.working_hours) //9am to 5 pm
You can also provide values within the bracket while adding decorators to the class and pass parameters within it. These parameters can be accessed as arguments within decorators.
Final Word
Decorators if support add will definitely help in properly implementing the requirements and we have to wait until the support gets added till then if you like to share the post with the colleagues.




