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.

This may not be accurate but the simplest way for you to understand is because the decorators will return another function instead here it is returning a value.

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.

You can also check out other related posts on React useEffect Hook

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
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.

Summary
Review Date
Reviewed Item
Implementation and Usage of Decorators in Javascript
Author Rating
51star1star1star1star1star
Software Name
Javascript
Software Name
Windows Os, Mac Os, Ubuntu Os
Software Category
Web Development