简体   繁体   English

如何在JavaScript中处理对象定义与实例化?

[英]How to handle object definition vs instantiation in JavaScript?

I am building a chess application and am running into an issue about the difference between object definition and instantiation in JavaScript. 我正在构建一个国际象棋应用程序,并且遇到了有关JavaScript中对象定义和实例化之间差异的问题。 For example, I want to separate my Board model (and view) from its representation (a nested array) via a Matrix model: 例如,我想通过Matrix模型将其Board模型(和视图)与其表示形式(嵌套数组)分开:

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.

And then Board looks like this: 然后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.

My issue is really in the definition of Board . 我的问题确实在于Board的定义。 When I instantiate a new Board object, I would like for it to subclass Matrix and then use Matrix 's methods to set pieces on the board. 当我实例化一个新的Board对象时,我希望它继承Matrix子类,然后使用Matrix的方法在板上设置零件。 But the problem is that Board does not have access to Matrix 's methods at instantiation, because that relationship is still being defined. 但是问题在于, Board在实例化时无法访问Matrix的方法,因为这种关系仍在定义中。

Trying to resolve this issue has clarified the answer to this question . 试图解决这个问题已经弄清了这个问题的答案。 It seems like the problem is that Board isn't a real subclass of Matrix . 似乎问题在于Board不是Matrix的真正子类。 That relationship is not set until the code actually executes. 在代码实际执行之前,不会设置该关系。 What is the JavaScript-esque way of handling this relationship? 处理这种关系的JavaScript风格是什么?

But the problem is that Board does not have access to Matrix's methods at instantiation, because that relationship is still being defined. 但是问题在于,董事会在实例化时无法访问Matrix的方法,因为这种关系仍在定义中。

No. When you use the new operator on Board , then first the relationship ("prototype chain") will be defined and after that the Board constructor function will be called on the new instance, where it can call the Matrix function on the instance or add instance properties like .state . 否。当您在Board上使用new运算符时,首先将定义关系(“原型链”),然后在新实例上调用Board构造函数,从而可以在实例上调用Matrix函数。添加实例属性,如.state You can use the prototypically inherited set method without any problems in there. 您可以使用原型继承的set方法,而不会出现任何问题。

Looking at Why is inheritance only defined at compile-time? 为何只在编译时定义继承?

In JavaScript, inheritance is set up at runtime. 在JavaScript中,继承是在运行时设置的。 You can declare the function body (using inherited methods in it), then set the prototype, then instantiate objects. 您可以声明函数体(使用其中的继承方法),然后设置原型,然后实例化对象。

 Board.prototype = Matrix.prototype; 

Don't do that . 不要那样做 You want Board.prototype = Object.create(Matrix.prototype) . 您需要Board.prototype = Object.create(Matrix.prototype)

This is incorrect: 这是不正确的:

Board.prototype = Matrix.prototype;

Do this instead so that additions to Board.prototype don't affect Matrix.prototype . 改为执行此操作,以便对Board.prototype添加不会影响Matrix.prototype

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

Now Board.prototype is an empty object that inherits from Matrix.prototype . 现在, Board.prototype是一个空对象,它继承自Matrix.prototype


I see no reason why your object created from Board won't have access to methods from Matrix.prototype , so I'd assume that you were perhaps overwriting or shadowing the Matrix.prototype methods. 我看不出为什么从Board创建的对象无法访问Matrix.prototype方法,因此我认为您可能正在覆盖或遮蔽Matrix.prototype方法。

The // etc. part of your code is likely the issue. 代码的// etc.部分可能是问题所在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM