2015-07-12 79 views
5

我目前工作的地方使用了下面的继承结构工程:经典的继承和对象池

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(); 

当然,使用这些两种模式的问题在于构造函数调用的子类型从类型的池不会画画。有没有办法解决这个问题,而没有转移到工厂结构?即有没有办法,在一个构造函数,做线沿线的东西:

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

知道它不能跨情境总是一致的,我也想保留继承结构,这样的instanceof等仍然可以工作:

+0

什么是“工厂结构”,为什么要避免这种情况? – Bergi

+0

通过工厂结构,我的意思是从构造函数/ new重构到'function Type(a){return {a:a}}'的行。至于为什么:这将涉及一定数量的重构,并排除使用一些内置的运算符(instanceof等) – Nodehead

+0

啊,我明白了。我以为你的意思是'Type.new'工厂... – Bergi

回答

4

使用这种模式的问题是,构造函数调用上SubTypeType的游泳池

其实,这不是一个问题,这是一个必然不会画。 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 
} 
+1

辉煌。谢谢(你的)信息。我还没有得到代表投票答案,但我已经标记为接受:回答我的问题!再次感谢。 – Nodehead

+1

@MrMe:你现在有这个特权:-)写得很好的问题提供者,欢迎来到Stack Overflow! – Bergi