jds
jds

Reputation: 8259

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. For example, I want to separate my Board model (and view) from its representation (a nested array) via a Matrix model:

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:

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. 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. But the problem is that Board does not have access to Matrix's methods at instantiation, because that relationship is still being defined.

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. That relationship is not set until the code actually executes. What is the JavaScript-esque way of handling this relationship?

Upvotes: 0

Views: 95

Answers (2)

Bergi
Bergi

Reputation: 664444

But the problem is that Board does not have access to Matrix's methods at instantiation, because that relationship is still being defined.

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. You can use the prototypically inherited set method without any problems in there.

Looking at Why is inheritance only defined at compile-time?

In JavaScript, inheritance is set up at runtime. 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).

Upvotes: 2

cookie monster
cookie monster

Reputation: 10972

This is incorrect:

Board.prototype = Matrix.prototype;

Do this instead so that additions to Board.prototype don't affect Matrix.prototype.

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

Now Board.prototype is an empty object that inherits from 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.

The // etc. part of your code is likely the issue.

Upvotes: 2

Related Questions