ts中文文档的mixins中有这样一段代码原地址
// Disposable Mixin
class Disposable {
isDisposed!: boolean;
dispose() {
this.isDisposed = true;
}
}
// Activatable Mixin
class Activatable {
isActive!: boolean;
constructor(){
console.log('??')
}
activate() {
this.isActive = true;
}
deactivate() {
this.isActive = false;
}
}
class SmartObject implements Disposable, Activatable {
constructor() {
console.log(this.constructor)
}
interact() {
this.activate();
}
// Disposable
isDisposed: boolean = false;
dispose!: () => void;
// Activatable
isActive: boolean = false;
activate!: () => void;
deactivate!: () => void;
}
applyMixins(SmartObject, [Disposable, Activatable]);
let desc = Object.getOwnPropertyDescriptor(SmartObject.prototype,'constructor')
console.log(desc,SmartObject.prototype.constructor === Activatable)
let smartObj = new SmartObject();
setTimeout(() => smartObj.interact(), 1000);
////////////////////////////////////////
// In your runtime library somewhere
////////////////////////////////////////
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
console.log(name)
derivedCtor.prototype[name] = baseCtor.prototype[name];
});
});
}
SmartObject类通过applyMixins方法混入了两个类,applyMixins方法中通过给被混入类属性赋值完成混入,我的问题是这个属性当中constructor也是能被复写的,执行混入后SmartObject的constructor也已经被覆盖成了Activatable类,可是new一个SmartObject执行的还是原来的constructor,Activatable类中的constructor并没有被执行,这是什么原理呢?如果说改变constructor指向并不会影响new执行时的函数,那么又如何将this.constructor的指向充Activatable类变回SmartObject中的构造函数呢?
无论改不改变SmartObject.prototype.constructor的指向,new SmartObject时调用的都是类SmartObject当中定义的constructor,在不是直接使用new SmartObject或者子类调用super()时调用的构造方法如this.constructor则会变为调用更改过的的prototype.constructor,在这个混入示例中,如果要将SmartObject的this.constructor指向回本身,应该在调用applyMixins后执行SmartObject.prototype.constructor = SmartObject,这样混入之后原型上的构造函数就能恢复正常了