Reputation: 11383
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();
}
}
Upvotes: 6
Views: 1460
Reputation: 161677
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;
};
Upvotes: 5