2014-10-26 47 views
1
var util = require('util'); 

function Entity(){ 
    //this.x == 10 at this point 
    this.x = 0; 
    this.y = 0; 
    this.globalInit(); 
} 

Entity.prototyp.globalInit = function(){ 
    console.log("this.x ", x); 
}; 

function Actor(){ 
    this.x = 10; 
    this.y = 10; 
    Actor.super_.apply(this, arguments); 
} 

util.inherits(Entity, Actor); 
var a = new Actor(); 
//outputs -> this.x 0 

我有这两个构造函数。我想要在子构造函数中定义的属性是最终的属性。我可以将Actor.super_.apply移动到构造函数的顶部,但有一个初始化逻辑(globalInit),我想保留在父构造函数的末尾node.js继承优先子构造函数属性

回答

1

我可以看到两个很好的解决方案。首先,父构造函数可以接受xy的参数,并将它们默认为父类的值。

function Entity(x, y){ 
    this.x = typeof x === 'undefined' ? 0 : x; 
    this.y = typeof y === 'undefined' ? 0 : y; 
    this.globalInit(); 
} 

function Actor(){ 
    Actor.super_.call(this, 10, 10); 
} 

这种方法将工作最好的,如果有不是很多特性,它不是一个问题,让他们在传递。它打破了几分,如果初始化是非常复杂的。

第二种方法在初始化非常复杂的情况下更具普遍性。本质上,您想要引入工厂方法来生成对象的实例,然后可以执行任意复杂的初始化。例如,

function Entity(){} 
function Actor(){} 

function createEntity(){ 
    var e = new Entity(); 
    e.x = 0; 
    e.y = 0; 
    e.globalInit(); 
    return e; 
} 

function createActor(){ 
    var a = new Actor(); 
    a.x = 10; 
    a.y = 10; 
    a.globalInit(); 
    return a; 
} 

很明显,这可以重构,以进一步干代码,可能与第一个解决方案的一些变体。

使用工厂方法而不是直接调用构造函数也会以其他方式增加值。它在一定程度上分离了两个模块,因此这些EntitiesActors的消费者不需要知道如何正确构建它们。它也允许你有多个不同的“构造函数”签名而不需要痛苦的论证分析。