Mastering JavaScript Decorators: From Python Concepts to ES6 Implementation
This article explains how decorators—originally popularized in Python—can be applied in JavaScript ES6, covering their syntax, class and property use cases, underlying mechanics with Object.defineProperty, and practical Babel transpilation steps.
Introduction
ES6 added class and extends, but sharing or extending behavior across multiple classes can become unwieldy. Decorators offer a more elegant solution.
Python Decorators Recap
A Python decorator is a function that takes another function, extending the behavior of the latter function without explicitly modifying it.
Introduced in Python 2.4, decorators wrap existing functions or classes to add new behavior without altering the original code.
def decorator(f):
print "my decorator"
return f
@decorator
def myfunc():
print "my function"
myfunc() # prints "my decorator" then "my function"The @decorator syntax shows how the wrapper runs before the original function.
Bringing Decorators to JavaScript
Before ES6, JavaScript developers manually added wrapper functions. With the decorator proposal (currently at stage 2), the syntax resembles Python, allowing annotations on classes and class members.
Basic Decorator Syntax in JavaScript
@decorator
class Cat {}
class Dog {
@decorator
run() {}
}The @ symbol marks a decorator, which can target a class or a method.
Class Decorator Example
function isAnimal(target) {
target.isAnimal = true;
return target;
}
@isAnimal
class Cat {}
console.log(Cat.isAnimal); // trueThis mirrors the Python example, adding a static property to the class.
Property (Method) Decorator Example
function readonly(target, name, descriptor) {
descriptor.writable = false;
return descriptor;
}
class Cat {
@readonly
say() { console.log("meow ~"); }
}
const kitty = new Cat();
kitty.say = function() { console.log("woof!"); };
kitty.say(); // still logs "meow ~"When applied to a method, the decorator receives target, name, and descriptor. It modifies the descriptor (via Object.defineProperty) to make the method read‑only.
Underlying Mechanism
Decorators on properties ultimately call Object.defineProperty with a descriptor containing value, enumerable, configurable, and writable flags.
Object.defineProperty(Cat.prototype, "say", {
value: function() { console.log("meow ~"); },
enumerable: false,
configurable: true,
writable: true
});By altering the descriptor, a decorator can enforce read‑only behavior, inject additional logic, or replace the original method.
Advanced Example: Enhancing a Method
function fast(target, name, descriptor) {
target.speed = 20;
const original = descriptor.value;
descriptor.value = function() {
original.call(this);
console.log(`speed ${this.speed}`);
};
return descriptor;
}
class Rabbit {
@fast
run() { console.log("running~"); }
}
const bunny = new Rabbit();
bunny.run(); // logs "running~" then "speed 20"
console.log(bunny.speed); // 20This decorator adds a speed property to the instance and wraps the original method to log the speed after execution.
Practical Usage and Transpilation
Because the decorator proposal is still a draft, most environments do not support it natively. Developers must use Babel with the legacy plugin:
babel --plugins transform-decorators-legacy es6.js > es5.jsAfter transpilation, the decorator logic is converted into standard ES5 code.
Conclusion
Decorators enable annotation and modification of classes and properties at design time, receiving target, name, and descriptor as arguments and optionally returning a new descriptor. While powerful, they require Babel for current browser compatibility.
References
https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.cmajiy3p1
https://github.com/wycats/javascript-decorators
http://www.artima.com/weblogs/viewpost.jsp?thread=240808
http://taobaofed.org/blog/2015/11/16/es7-decorator/
https://github.com/jayphelps/core-decorators.js
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.
Aotu Lab
Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.
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.
