Mixin模式和原型构造器

时间:2019-01-11 10:41:49

标签: javascript typescript

昨天我听说过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 !?
  • 根据MDN documentation构造函数属性返回对创建实例对象的对象构造函数的引用。,现在不再如此了,因为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];
    })
  })
}

0 个答案:

没有答案