2014-02-10 119 views
0

我正在构建一个国际象棋应用程序,并且遇到了有关JavaScript中对象定义和实例化之间差异的问题。例如,我想我Board模型(以及视图)与它的表示(嵌套数组)通过Matrix模型分开:如何在JavaScript中处理对象定义与实例化?

var Matrix = function(n, m) { 
    // builds an n*m nested array 
    // e.g. a 2x3 array would look like this: 
    // [[0, 0], [0, 0], [0, 0]] 
}; 

// A setter, which takes a `Point` object and correctly updates the nested array 
Matrix.prototype.set = function(pt, obj) { 
    this.state[pt.y][pt.x] = obj; 
}; 

// A custom `each` method that iterates over the nested array 
Matrix.prototype.each = function(fn) { 
    // executes `fn` against every (x,y) in the nested array 
}; 

// etc. 

然后Board看起来是这样的:

var Board = function(n, m) { 
    Matrix.call(this, n, m); 

    // now use `Matrix`'s `set` method to place pieces on the board. 
}; 

Board.prototype = Matrix.prototype; 

// etc. 

我的问题真的在Board的定义。当我实例化一个新的Board对象时,我想要它的子类Matrix,然后使用Matrix的方法在板上设置棋子。但问题是Board在实例化时无法访问Matrix的方法,因为该关系仍在定义中。

试图解决此问题已澄清了this question的答案。看起来问题是Board不是Matrix的真实子类。直到代码实际执行时才会设置该关系。什么是处理这种关系的JavaScript式的方式?

+1

'Board.prototype = Matrix.prototype;'是一个坏主意。你需要'Board.prototype = Object.create(Matrix.prototype);'(如果Object.create的功能的相关子集需要填充shim)。 –

回答

2

但问题是,董事会在实例化时无法访问Matrix的方法,因为该关系仍在定义中。

号当您使用Boardnew operator,那么首先的关系(“原型链”)将被定义后,该Board构造函数将在新的实例调用,它可以调用Matrix函数或添加实例属性,如.state。您可以使用原型继承的set方法,在那里没有任何问题。

看着Why is inheritance only defined at compile-time?

在JavaScript中,继承是在运行时设置。你可以声明函数体(使用继承的方法),然后设置原型,然后实例化对象。

Board.prototype = Matrix.prototype; 

Don't do that。你想要Board.prototype = Object.create(Matrix.prototype)

+2

我并没有看到在这方面降薪的原因,Bergi对你真正尝试使用Board的构造函数时会发生什么非常正确。 –

+0

我不认为这个答案值得downvotes。我假设*“...将在新实例上调用构造函数*”引用矩阵构造函数。 –

+0

@cookiemonster:我确实提到了Board的构造函数。确实,它叫'矩阵'。 – Bergi

2

这是不正确的:

Board.prototype = Matrix.prototype; 

做到这一点,而不是让补充Board.prototype不影响Matrix.prototype

Board.prototype = Object.create(Matrix.prototype); 

现在Board.prototype是一个空对象从Matrix.prototype继承。


我看不出为什么你的对象从Board创建不会有从Matrix.prototype访问方法,所以我会假设你或许覆盖或遮蔽的Matrix.prototype方法。

// etc.部分代码可能是问题所在。