昨天我听说过mixin pattern,我正在尝试,但我对我认为是基本概念感到困惑。
让我们专注于此功能:
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
});
});
}
在基本构造函数原型迭代中,属性名称之一为constructor
。因此,我们要做的是将派生类原型构造函数重新分配给最后一个baseClass原型构造函数。
假设我们有三个班级:
class Disposable {
public isDisposed: boolean;
public dispose() {
this.isDisposed = true;
}
}
class Activable {
public isActive: boolean;
public activate() {
this.isActive = true;
}
public deactivate(){
this.isActive = false;
}
}
class MyDisposableObject implements Disposable, Activable {
//Disposable
public isDisposed = false;
public dispose: () => void;
//Activable
public isActive = false;
public activate:() => void;
public deactivate:() => void;
}
在applyMixins(MyDisposableObject, [Disposable, Activable])
之后,我们不再对MyDisposableObject实例拥有正确的构造函数。
const m = new MyDisposableObject();
console.log(m.constructor); // output : f Activable() {}
console.log(m instanceof MyDisposableObject) //output : true !?
applyMixins
重新分配了派生类.prototype.constructor。这不会导致副作用吗?
var Disposable = /** @class */ (function () {
function Disposable() {
}
Disposable.prototype.dispose = function () {
this.isDisposed = true;
};
return Disposable;
}());
var Activable = /** @class */ (function () {
function Activable() {
}
Activable.prototype.activate = function () {
this.isActive = true;
};
Activable.prototype.deactivate = function () {
this.isActive = false;
};
return Activable;
}());
var MyDisposableObject = /** @class */ (function () {
function MyDisposableObject() {
//Disposable
this.isDisposed = false;
//Activable
this.isActive = false;
}
return MyDisposableObject;
}());
applyMixins(MyDisposableObject, [Disposable, Activable]);
function applyMixins(derived, bases) {
bases.forEach(function (base) {
Object.getOwnPropertyNames(base.prototype).forEach(function (name) {
derived.prototype[name] = base.prototype[name];
});
});
}
var m = new MyDisposableObject();
console.log('m constructor :', m.constructor);
console.log('m instanceof MyDisposableObject : ', m instanceof MyDisposableObject);
我仍然不明白为什么文档示例会重新分配 derivedClass.prototype 的构造函数,并且如果这是否有害,那么在我等待一个很好的解释时,我修改了applyMixins以忽略构造函数属性:
function applyMixins(derived, bases) {
bases.forEach((base) => {
Object.getOwnPropertyNames(base.prototype)
.filter((name) => name.toLowerCase() !== 'constructor')
.forEach((name) => {
derived.prototype[name] = base.prototype[name];
})
})
}