How can I override a constructor with an ES7 class decorator?
For example, I'd like to have something like:
@injectAttributes({ foo: 42 })
class Bar {
constructor() {
console.log(this.foo);
}
}
Where the injectAttributes
decorator will inject attributes into new instances before they are created:
> bar = new Bar();
42
> bar.foo
42
The obvious solution – using a different constructor:
function overrideConstructor(cls, attrs) {
Object.assign(this, attrs);
cls.call(this);
}
Does not work because the object created will be an instance of the new constructor, not the original type:
> bar = new overrideConstructor(Bar, {foo: 42})
42
> bar
[overrideConstructor {}]
> bar instanceof Bar
false
The BabelJS REPL doesn't support decorators so I am using the function (and manually wrapping) but the concept is the same.
Here is the code working, and the copy/paste below:
function injectAttributes(cls, attrs) {
const injected = function(...args) {
Object.assign(this, attrs);
return cls.apply(this, args);
}
injected.prototype = cls.prototype;
return injected;
}
class BareBar {
constructor() {
console.log(this.foo);
}
}
const Bar = injectAttributes(new BareBar, { foo: 5 })
const thing = new Bar();
console.log(thing instanceof Bar);
This prints:
5
true
The decorator creates a new constructor, where attributes are injected, and then copies over the original prototype so that instanceof
works.
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