Decorators in JavaScript

What Are Decorators in JavaScript?

Decorators are a feature in JavaScript that allows you to add additional functionality to classes and their methods without altering the original code. Think of them like wrappers that extend the behavior of functions or properties.

Although decorators are not yet fully supported in JavaScript, they are being actively worked on and are already widely used in TypeScript and other JavaScript frameworks. In simple terms, a decorator is a function that takes an existing piece of code (like a method or property) and adds something new to it.

How Do Decorators Work?

Let's look at a simple example. Imagine you want to log every time a function is called. Instead of adding a console.log statement in every function, you can create a decorator to handle this.

Simple Method Decorator Example

Here’s how you can use a decorator to log when a function is called:

function logMethod(target, key, descriptor) {
  const originalFunction = descriptor.value;

  descriptor.value = function(...args) {
    console.log(`Called method: ${key}`);
    return originalFunction.apply(this, args);
  };

  return descriptor;
}

class Calculator {
  @logMethod
  add(a, b) {
    return a + b;
  }
}

const calculator = new Calculator();
console.log(calculator.add(5, 3)); // Output: Called method: add
                                   // 8

In this example, the @logMethod decorator wraps the add method. Every time you call add, it logs the method name and then continues executing the original function.

Class Decorator Example

You can also create decorators that modify entire classes. For example, let’s say you want to automatically track the number of times a class is instantiated:

function trackInstances(target) {
target.instanceCount = 0;

const originalConstructor = target;

const newConstructor = function(...args) {
target.instanceCount++;
return new originalConstructor(...args);
};

return newConstructor;
}

@trackInstances
class User {
constructor(name) {
this.name = name;
}
}

const user1 = new User('Alice');
const user2 = new User('Bob');

console.log(User.instanceCount); // Output: 2

The @trackInstances decorator adds a new property instanceCount to the class to keep track of how many instances have been created.

Why Use Decorators?

Decorators are useful when you want to:

  • Add functionality to multiple functions or classes in a consistent way.
  • Keep your code clean by separating extra behaviors like logging, validation, or tracking from the core logic.
  • Avoid repetition and Modularity by reusing common behaviors across different parts of your application.

Conclusion

Decorators are a simple but powerful feature that can help you make your code more modular and maintainable. By wrapping extra behavior around your methods or classes, you can add functionality without modifying the core logic. As decorators become more widely supported in JavaScript, they will be an invaluable tool for developers.


Leave a Reply

Your email address will not be published. Required fields are marked *