Frontend Development 13 min read

Understanding and Using Decorators in JavaScript (Frontend Development)

This article introduces JavaScript decorators, explains their relation to the decorator design pattern, shows how to configure Babel for decorator support, demonstrates class and method decorator syntax with detailed code examples, and discusses practical usage scenarios and execution order in modern front‑end projects.

政采云技术
政采云技术
政采云技术
Understanding and Using Decorators in JavaScript (Frontend Development)

Preface

In front‑end development you may have encountered syntax like @methodName and wondered what it does. The answer is the Decorator (or Decorator ) pattern, which allows dynamic addition of behavior to classes without modifying the original class definition.

What Is a Decorator

Decorator Pattern

The decorator pattern lets you add responsibilities to an object at runtime while keeping the object itself unchanged, similar to putting on different clothes for different weather.

In JavaScript, a Decorator is a syntactic sugar for this pattern, currently at Stage 2 of the TC39 proposal and requires Babel compilation.

How to Use Decorators

Third‑Party Library Usage

Babel ≥ 7.x

Install: npm install --save-dev @babel/plugin-proposal-decorators

Configure .babelrc : { "plugins": [ ["@babel/plugin-proposal-decorators", { "legacy": true }] ] }

Babel ≤ 6.x

Install: npm install --save-dev babel-plugin-transform-decorators-legacy

Configure .babelrc : { "plugins": ["transform-decorators-legacy"] }

Usage Syntax

A decorator is written as @ + expression returning a decorator function . Example:

@classDecorator
class TargetClass {
  // class
  @fieldDecorator
  targetField = 0; // instance property

  @funDecorator
  targetFun() {}

  @accessorDecorator
  get targetGetFun() {}
}

When multiple decorators are applied, they are executed from the outermost to the innermost (enter) and then from innermost to outermost (exit).

Scope of Decorators

Classes

Class instance properties (public, private, static)

Class methods (public, private, static)

Class accessors (getters/setters)

Function Decoration Limitation

Functions cannot be directly decorated because of function hoisting. To modify a function you can use higher‑order functions instead.

Decorator Principles

Class Decorators

Passing Arguments

function decorator(...args) {
  args.forEach((arg, index) => {
    console.log(`参数${index}`, arg);
  });
}

@decorator
class TargetClass {}

The decorator receives the class definition as its sole argument.

Return Value

function returnStr(targetClass) {
  return 'hello world~';
}
function returnClass(targetClass) {
  return targetClass;
}

@returnStr
class ClassA {}
@returnClass
class ClassB {}

The decorator’s return value replaces the original class if it is truthy.

Practical Examples

Add a static attribute: function addAttribute(targetClass) { targetClass.isUseDecorator = true; } @addAttribute class TargetClass {} console.log(TargetClass.isUseDecorator); // true

Return a decorator factory to set custom content: function addAttribute(content) { return function decFn(targetClass) { targetClass.content = content; return targetClass; }; } @addAttribute('这是内容~~~') class TargetClass {} console.log(TargetClass.content); // 这是内容~~~

Add a prototype method: function decorator(targetClass) { targetClass.prototype.decFun = function () { console.log('这里是装饰器 decorator 添加的原型方法 decFun~'); }; } @decorator class TargetClass {} const instance = new TargetClass(); instance.decFun();

Method Decorators

Method decorators receive three arguments: the class prototype, the property name, and the property descriptor, similar to Object.defineProperty .

function readonly(target, name, descriptor) {
  descriptor.writable = false;
  return descriptor;
}
class Person {
  @readonly
  name = 'zhangsan';
}
const person = new Person();
console.log(person.name, Object.getOwnPropertyDescriptor(person, 'name'));

Decorator Applications

Decorators can encapsulate repetitive logic such as data fetching in React components. By creating a getData decorator that wraps a component, you can centralize API calls and pass the fetched data via props.

// Decorator definition
function getData(params) {
  return (Comp) => {
    class WrapperComponent extends Component {
      async getData() {
        const data = await request('/xxx', { params });
        this.setState({ data });
      }
      render() {
        return
;
      }
    };
    return WrapperComponent;
  };
}

// Component usage
@getData({ id: '123' })
export default class Index extends Component {
  render() {
    const data = this.props.data;
    return
我是组件一: {data}
;
  }
}

Conclusion

The article covered the concept, syntax, configuration, execution order, and practical use cases of JavaScript decorators, providing numerous code samples to help front‑end developers apply decorators effectively in their projects.

FrontendJavaScriptBabelDesign Patterndecoratorclass
政采云技术
Written by

政采云技术

ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.