我正在尝试在类实例中添加一些属性(比如插件系统)。 为此,我遵循这个example来使用类装饰器:
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();
但它不起作用:因为目标是一个类,我得到这个错误:
return original.apply(this, args);
^
TypeError: Class constructor AClass cannot be invoked without 'new'
据我所知,由于Class构造函数(不是原型函数“构造函数”),我不能这样做。
所以我尝试将此代码改编为:
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();
有了这个,bInstance就不再是BClass的一个实例了。所以它也不起作用。所以我收到了这个错误:
bInstance.bar();
^
TypeError: bInstance.bar is not a function
有什么建议吗?
感谢。
答案 0 :(得分:0)
以防有人仍然需要这个。在装饰器内部,而不是通过函数创建包装器,可以使用新的类包装器创建它:
function testDecorator(target:any) {
return class extends target {
constructor (...args) {
console.log(`New: ${target.name}`);
super(...args);
}
}
}