Master JavaScript Decorators: A Practical Guide to ES7 Enhancements
This article explains what JavaScript decorators are, how they work on classes and methods, how to configure Babel for ES7 support, and demonstrates real‑world uses such as mixins and simple AOP, providing clear code examples throughout.
Decorator Learning Summary
1. What is a decorator
A decorator is a wrapper syntax introduced in ES7 that can dynamically enhance classes or instance methods without the target being aware.
Readers interested can further study the Decorator Pattern.
In ES7, a decorator is just syntactic sugar, similar to class.
Refer to the Babel‑transformed ES5 code for details.
2. How to use decorators
2.1. On class methods
Decorators can be applied to class methods, as shown below:
function readonly(target, key, descriptor) {
descriptor.writable = false;
return descriptor;
}
class People {
@readonly
sayName() {
console.log(this.name);
}
}
var p = new People();
p.sayName = 'hello';Running this code throws an error.
The decorator’s signature is function(target, key, descriptor) where:
target : the class prototype, e.g., People.prototype key : the property name, e.g., sayName descriptor : the property descriptor
This signature matches Object.defineProperty, making a method decorator essentially a wrapper around it.
2.2. On classes
Decorators can also enhance a class itself:
function nonTestable(target) {
target.canTest = false;
}
@nonTestable
class People {}
console.log(People.canTest); // falseWhen applied to a class, only the class constructor is passed.
2.3. Decorator factories
When the same decorator needs different behavior on different targets, it can be written as a factory function:
function addName(name) {
return function(target) {
target.myName = name;
};
}
@addName('people')
class People {
static say() {
console.log(People.myName);
}
}
@addName('dog')
class Dog {
static say() {
console.log(Dog.myName);
}
}
People.say(); // people
Dog.say(); // dog3. How to enable decorators
Because decorators are an ES7 feature, Babel must be used to transpile them. Example .babelrc configuration:
{
"presets": ["es2015", "stage-1"],
"plugins": [
"babel-plugin-transform-decorators-legacy"
]
}Install the required packages:
npm i babel-cli babel-preset-es2015 babel-preset-stage-1 babel-plugin-transform-decoratorsThen transpile:
babel index.js > index.es5.js4. Practical applications
4.1. Implementing mixins
Example of using decorators as mixins:
function nameMixin(target) {
target.prototype.setName = function(name) {
this.name = name;
return this;
};
target.prototype.sayName = function() {
console.log(this.name);
};
}
function ageMixin(target) {
target.prototype.setAge = function(age) {
this.age = age;
return this;
};
target.prototype.sayAge = function() {
console.log(this.age);
};
}
@nameMixin
@ageMixin
class People {}
var p = new People();
p.setName('peter').sayName(); // peter
p.setAge(18).sayAge(); // 18Compared with traditional mixin usage, decorators make the code clearer.
4.2. Simple AOP
Decorators can also implement Aspect‑Oriented Programming:
function aop(before, after) {
return function(target, key, descriptor) {
const method = descriptor.value;
descriptor.value = (...args) => {
let ret;
before && before(...args);
ret = method.apply(target, args);
if (after) {
ret = after(ret);
}
return ret;
};
};
}
function beforeTest1(opt) {
opt.name = opt.name + ', haha';
}
function beforeTest2(...args) {}
function afterTest2(ret) {
console.log('haha, add 10!');
return ret + 10;
}
class Test {
@aop(beforeTest1)
static test1(opt) {
console.log(`hello, ${opt.name}`);
}
@aop(beforeTest2, afterTest2)
static test2(...args) {
return args.reduce((a, b) => a + b);
}
}
Test.test1({ name: 'peter' });
console.log(Test.test2(1, 2, 3));The example shows how a decorator can run code before and after a method, resulting in clearer logic.
5. Summary
Decorators are an ES7 syntactic sugar that provide powerful, readable ways to extend classes and methods. Any code that follows the Decorator Pattern can be expressed with decorators, and Babel enables their use today.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Tencent IMWeb Frontend Team
IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
