Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In javascript, should I add functions to object or object prototype [duplicate]

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?

like image 730
Nescio Avatar asked Sep 27 '22 19:09

Nescio


1 Answers

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).

like image 196
aug2uag Avatar answered Oct 03 '22 22:10

aug2uag