我正在构建一个国际象棋应用程序,并且遇到了一个关于JavaScript中对象定义和实例化之间差异的问题。例如,我想通过Board
模型将Matrix
模型(和视图)与其表示(嵌套数组)分开:
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式方式是什么?
答案 0 :(得分:2)
但问题是Board在实例化时无法访问Matrix的方法,因为该关系仍在定义中。
没有。在Board
上使用new
operator时,首先定义关系(“原型链”),然后在新实例上调用Board
构造函数,在那里它可以调用实例上的Matrix
函数或添加.state
之类的实例属性。您可以使用原型继承的set
方法,而不会出现任何问题。
在JavaScript中,继承是在运行时设置的。您可以声明函数体(使用其中的继承方法),然后设置原型,然后实例化对象。
Board.prototype = Matrix.prototype;
Don't do that。你想要Board.prototype = Object.create(Matrix.prototype)
。
答案 1 :(得分: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.
部分可能就是问题。