Courses Blog About
Post updated at  

Decorators in JavaScript: a deep dive with examples

decorators

Decorators (Decorators) are powerful JavaScript functionality that allows you to modify the behavior of classes and their methods. Although they are still in the proposal stage (Stage 3), decorators are actively used with translators (Babel, TypeScript).

How decorators work in JavaScript

Decorators are special functions that are applied to classes, methods, properties, or function parameters. They start with the @ symbol and are placed immediately before the announcement of what they decorate.

The main types of decorators

  1. Class decorators - modify the entire class
  2. Method decorators - change the behavior of class methods
  3. Property Decorators - work with class properties
  4. Parameter decorators - modify method parameters

How decorators work

// A simple method decorator
function log(target, name, descriptor) {
  const originalMethod = descriptor.value;
  
  descriptor.value = function(...args) {
    console.log(`Вызов метода ${name} с аргументами: ${args}`);
    const result = originalMethod.apply(this, args);
    console.log(`Метод ${name} вернул: ${result}`);
    return result;
  };
  
  return descriptor;
}

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

const calc = new Calculator();
calc.add(2, 3); // Blocks the call and the result

How it works

  1. The decorator gets three arguments:
    • target the class to which the method belongs
    • name name of the method being decorated
    • descriptor method descriptor object (as in Object.defineProperty)
  2. The decorator modifies the behavior by wrapping the original method.

Using decorators in Vue

In Vue decorators are especially useful with TypeScript and libraries like vue-class-component.

Let’s look at practical examples with the Composition API

Decorators for API calls

// A decorator for managing the loading state
export function WithLoading() {
  return function(target: any, key: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    const loadingKey = `${key}Loading`;
    
    // Adding the download status property
    target[loadingKey] = ref(false);
    
    descriptor.value = async function(...args: any[]) {
      try {
        this[loadingKey].value = true;
        return await originalMethod.apply(this, args);
      } finally {
        this[loadingKey].value = false;
      }
    };
    
    return descriptor;
  };
}

// Example of usage in a component
export default class UserComponent {
  @WithLoading()
  async fetchUserData(userId: string): Promise<User> {
    const response = await fetch(`/api/users/${userId}`);
    return response.json();
  }

  // The download status will be automatically created as
  // fetchUserDataLoading: Ref<boolean>
}

The composition of the decorators

// A decorator for caching results
// 5 minutes by default
function Cache(maxAge: number = 300000) { 
  return function(target: any, key: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    const cache = new Map();
    
    descriptor.value = function(...args: any[]) {
      const cacheKey = JSON.stringify(args);
      
      if (cache.has(cacheKey)) {
        const { timestamp, value } = cache.get(cacheKey);
        if (Date.now() - timestamp < maxAge) {
          return value;
        }
      }
      
      const result = originalMethod.apply(this, args);
      cache.set(cacheKey, { value: result, timestamp: Date.now() });
      return result;
    };
    
    return descriptor;
  };
}

// Usage example
class ApiService {
  @Cache(60000) // Cache for 1 minute
  @WithLoading()
  async fetchData(endpoint: string) {
    // ...
  }
}

Advantages and disadvantages of decorators in Vue

Advantages

Disadvantages

Conclusion

Decorators in JavaScript provide a powerful way to modify the behavior of classes and methods. In Vue they are especially useful for:

Although the decorators are still in the proposal stage, they can be used in your projects. When applied correctly, they can significantly improve the readability and maintainability of the code.

frontline

FrontLine

Join us in telegram

Other interesting posts in a convenient format

Subscribe

More interesting on the topic