I am building a chess game in javascript right now, and am a little unsure about the correct way to work with inheritance. On one part of the code I have a piece object with different piece types extending it, for example with a knight (as it's the shortest) it looks like this (without the comments):
pieces
/************* piece ********************/
function Piece(square, color) {
this.square = square;
this.color = color;
}
Piece.prototype.get_path = function(to) {
return null;
};
Piece.prototype.get_capture_path = function(to) {
return this.get_path(to);
};
Piece.prototype.isAt= function(square) {
return (this.square.equals(square));
};
/************* KNIGHT *****************/
Knight.prototype = Object.create(Piece.prototype);
Knight.prototype.constructor = Knight;
function Knight(square, color) {
Piece.call(this, square, color);
this.type = KNIGHT;
}
Knight.prototype.get_path = function(to) {
var h_movement = Math.abs(this.square.file - to.file);
var v_movement = Math.abs(this.square.rank - to.rank);
if ((h_movement === 2 && v_movement === 1) || (h_movement === 1 && v_movement === 2)) {
return [to];
}
return null;
};
And it works fine, as you would expect the object looks as follow according to chrome's console.log output:
Knight {square: Square, color: "w", type: "N"}
color: "w"
square: Square
type: "N"
__proto__: Knight
constructor: Knight(square, color)
get_path: (to)
__proto__: Piece
Now in a different file of the code, I have the definition of a square object, which looks like this:
Square
function Square(file, rank) {
this.file = file;
this.rank = rank;
this.equals = function(other) {
return (this.file === other.file && this.rank === other.rank);
};
this.toString = function() {
return String(file) + ' ' + String(rank);
};
this.getSquareAtOffset = function(file, rank) {
file = Number(file)? file : 0;
rank = Number(rank)? rank : 0;
return new Square(this.file + file, this.rank + rank);
}
};
This also works fine, and, as you would probably expect, the console log of the object is as follow:
Square {file: 1, rank: 1}
equals: (other)
file: 1
getSquareAtOffset: (file, rank)
rank: 1
toString: ()
__proto__: Square
This also works fine. So my question is, which approach is better at which situation? What is the difference between the two objects apart from one having it's function as a property and the other having it as a property of the prototype?
The actual preferred or recommended way of writing is as an object:
var Square = {};
Square.file = file;
Square.rank = rank;
Square.equals = function(other) {
return (this.file === other.file && this.rank === other.rank);
};
Square.toString = function() {
return String(file) + ' ' + String(rank);
};
Square.getSquareAtOffset = function(file, rank) {
file = Number(file)? file : 0;
rank = Number(rank)? rank : 0;
return new Square(this.file + file, this.rank + rank);
};
Reference: http://javascript.crockford.com/prototypal.html
With that said, many top projects use other, and including Prototypical, pattern(s).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With