问题
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
回答1:
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(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.
来源:https://stackoverflow.com/questions/40796074/override-constructor-with-an-class-decorator