Is it possible to define a decorator that would be exposed at an instance level in the current iteration of the proposal
For example
function once(target, name, descriptor) {
let {get} = descriptor;
var called = false, result;
if (typeof get === "function") {
descriptor.get = function() {
console.log(called);
if (!called) {
result = get.apply(this, arguments);
called = true;
}
return result;
}
}
return descriptor;
};
class X {
@once
get y() {
return Math.random();
}
}
var x1 = new X;
var x2 = new X;
// Should be false
console.log(x1.y !== x2.y)
I'm wanting behaviour similar to doing
class X2 {
constructor() {
// Set descriptor manually for this instance
let descriptor = Object.getOwnPropertyDescriptor(X2.prototype, 'y');
let d = Object.assign({}, descriptor);
once(X, "y", d);
Object.defineProperty(this, 'y', d);
}
get y() {
return Math.random();
}
}
Babel REPL example
Since the decorator pattern involves wrapping a piece of code with another without modifying the wrapped code, decorators have been in use in JavaScript in the form of higher-order functions and function composition. Using higher-order functions we can imperatively decorate a piece of code in JavaScript.
Decorators provide a way to add both annotations and a meta-programming syntax for class declarations and members. Decorators are a stage 2 proposal for JavaScript and are available as an experimental feature of TypeScript. NOTE Decorators are an experimental feature that may change in future releases.
A Decorator is a special kind of declaration that can be applied to classes, methods, accessor, property, or parameter. Decorators are simply functions that are prefixed @expression symbol, where expression must evaluate to a function that will be called at runtime with information about the decorated declaration.
Decorators accept a function and return a function This function accept a number and returns either True or False depending on whether that number is prime or not.
Decorators only run once when the class is defined, but that doesn't mean that the definition-time logic can't set up the function to do stuff per-instance. In this case, you could memoize the value by defining an instance-specific property inside the prototye-level getter;
function once(target, name, descriptor) {
let {get, writable, enumerable} = descriptor;
if (typeof get === "function") {
descriptor.get = function() {
const value = get.apply(this, arguments);
Object.defineProperty(this, name, {
value,
writable,
enumerable
});
return value;
}
}
return descriptor;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With