经典继承与对象汇集

时间:2015-07-12 15:04:19

标签: javascript

我目前正在开发一个使用以下继承结构的项目:

var Type = function(a){
  this.a = a;
};

var SubType = function(a){
  Type.call(this, a);
};
SubType.prototype = Object.create(Type.prototype);
SubType.prototype.constructor = SubType;

现在,我正在尝试将一些对象池添加到等式中。我目前使用的模式类似于(伪代码):

Type.new = function(){
  if object available in pool
    reset popped pool object 
    return pool object
  else
    return new Type()
}
var a = Type.new();

当然,使用这两种模式的问题是SubType上的构造函数调用不会从Type的池中绘制。如果没有搬到工厂结构,有没有办法解决这个问题?即在构造函数中,有没有办法按照以下方式执行某些操作:

var SubType = function(){
  build on top of instanceReturnedFromFunction()
};

知道它在上下文中并不总是一致的,我还想保留继承结构,以便instanceof等仍然可以工作:

1 个答案:

答案 0 :(得分:4)

  

使用此模式的问题是SubType上的构造函数调用不会从Type池中提取

事实上,这不是一个问题,这是必要的。 TypeSubType个实例有不同的原型,您不能互换使用它们(和swapping prototypes doesn't work either)。
您肯定需要为所有课程设置单独的池。你可以毫无问题地使用.new工厂方法 - 当然你应该以编程方式创建这些工厂:

function pooledNew() {
    // `this` is the "class" constructor function
    if (!this.pool) this.pool = [];
    var instance = this.pool.length ? this.pool.pop() : Object.create(this.prototype);
    this.apply(instance, arguments); // reset / initialise
    return instance;
}
function makePooling(constr) {
    constr.new = pooledNew;
    constr.pool = [];
    var proto = constr.prototype;
    if (proto.constructor !== constr)
        proto.constructor = constr;
    if (typeof proto.destroy != "function")
        proto.destroy = function destroyInstance() {
            this.constructor.pool.push(this);
        };
    return constr;
}

这些设计用于完成子类化,在您的示例中只需执行

makePooling(Type);
makePooling(SubType);

在ES6中,子类甚至会从超类构造函数继承new方法。

class Type {
    constructor(a) {
        this.a = a;
    }
    destroy() { // overwriting default behaviour
        this.a = null; // for GC
        this.constructor.pool.push(this);
    }
}
makePooling(Type);

class SubType extends Type {
    // you can use super calls in both "constructor" and "destroy" methods
}