问题
I'm trying to add some properties in class instances (like a Plugin system). For that, I followed this example to do that with a Class Decorator:
function testDecorator(target:any) {
// save a reference to the original constructor
var original = target;
// the new constructor behaviour
var f : any = function (...args: any[]) {
console.log("New: " + original.name);
return original.apply(this, args)
}
// copy prototype so intanceof operator still works
f.prototype = original.prototype;
// return new constructor (will override original)
return f;
}
class AbstractClass {
constructor() {
console.log('Init AbstractClass');
}
}
@testDecorator
class AClass extends AbstractClass {
constructor() {
super();
console.log('Init AClass');
}
foo() {
console.log('Launch foo');
}
}
class BClass extends AClass {
constructor() {
super();
console.log('Init BClass');
}
bar() {
console.log('Launch bar');
}
}
var bInstance = new BClass();
bInstance.foo();
bInstance.bar();
But it doesn't work: as target is a class, I get this error:
return original.apply(this, args);
^
TypeError: Class constructor AClass cannot be invoked without 'new'
I understand that I cannot do that because of Class constructor (not prototype function "constructor").
So I tried to adapt this code to:
function testDecorator(target:any) {
// save a reference to the original constructor
var original = target;
// the new constructor behaviour
var f : any = function (...args: any[]) {
console.log("New: " + original.name);
return new original(...args)
}
// copy prototype so instanceof operator still works
f.prototype = original.prototype;
// return new constructor (will override original)
return f;
}
class AbstractClass {
constructor() {
console.log('Init AbstractClass');
}
}
@testDecorator
class AClass extends AbstractClass {
constructor() {
super();
console.log('Init AClass');
}
foo() {
console.log('Launch foo');
}
}
class BClass extends AClass {
constructor() {
super();
console.log('Init BClass');
}
bar() {
console.log('Launch bar');
}
}
var bInstance = new BClass();
bInstance.foo();
console.log(bInstance instanceof AClass);// true
console.log(bInstance instanceof BClass);// false
bInstance.bar();
With that, bInstance is not an instance of BClass anymore. So it doesn't work also. So I get this error:
bInstance.bar();
^
TypeError: bInstance.bar is not a function
Any suggestion?
Thanks.
回答1:
In case somebody would still need this. Inside the decorator instead of creating the wrapper via function, you can create it with a new class wrapper:
function testDecorator(target:any) {
return class extends target {
constructor (...args) {
console.log(`New: ${target.name}`);
super(...args);
}
}
}
来源:https://stackoverflow.com/questions/41220382/javascript-decorator-on-class-constructor