类构造函数上的JavaScript装饰器
我试图在类实例中添加一些属性(比如插件系统)。 为此,我使用一个类装饰器遵循以下步骤:类构造函数上的JavaScript装饰器,javascript,class,typescript,decorator,ecmascript-next,Javascript,Class,Typescript,Decorator,Ecmascript Next,我试图在类实例中添加一些属性(比如插件系统)。 为此,我使用一个类装饰器遵循以下步骤: function testDecorator(target:any) { // save a reference to the original constructor var original = target; // the new constructor behaviour var f : any = function (...args: any[]) {
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();
但它不起作用:因为target是一个类,所以我得到以下错误:
return original.apply(this, args);
^
TypeError: Class constructor AClass cannot be invoked without 'new'
bInstance.bar();
^
TypeError: bInstance.bar is not a function
我知道我不能这样做,因为类构造函数(不是原型函数“构造函数”)
因此,我尝试将此代码改编为:
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();
因此,BinInstance不再是BClass的实例。所以它也不起作用。所以我得到了这个错误:
return original.apply(this, args);
^
TypeError: Class constructor AClass cannot be invoked without 'new'
bInstance.bar();
^
TypeError: bInstance.bar is not a function
有什么建议吗
谢谢。以防有人还需要这个。在装饰器内部,您可以使用新的类包装器创建包装器,而不是通过函数创建包装器:
function testDecorator(target:any) {
return class extends target {
constructor (...args) {
console.log(`New: ${target.name}`);
super(...args);
}
}
}