简体   繁体   中英

How to extend a class in JavaScript

I'm working on a chess game built in JavaScript. I'm taking an object-oriented approach to it and am having some difficulty working with JavaScript's inheritance. I want there to be a "Piece" abstract class that holds some fields and basic getters/setters such as is this piece black or white. I then want to have classes for each type of piece that I can instantiate like so:

var pieceOne = new Pawn();

The Pawn() should have all the fields and methods of Piece but have its own method for movement, and additional fields (such as whether or not it has moved yet, as this doesn't matter for most pieces). Here's my current Piece class:

//This object specifies basic information about pieces.
"use strict";
function Piece(color, type, captured, hasMoved) {    
    this.color = color;
    this.type = type;
    this.captured = captured;
    this.hasMoved = hasMoved;
    this.image = color + "_" + type + ".svg";
}
Piece.prototype.getImage = function getImage(){
    return this.image;
}
Piece.prototype.isCaptured = function isCaptured(){
    return this.captured;
};

I know if I am going to make a subclass for every kind of piece that I'd probably eliminate the "type" field, but how could I make a Pawn subclass? Something like this?

function Pawn() = new Piece(color, captured, hasMoved);
Pawn.prototype.getLegalMoves = function getLegalMoves(){
    //return legal moves
}
var pieceOne = new Pawn("black", false, false);

Extending a class can be done in different ways. The simplest method to extend an class is to use Object.create method. This is common method which is used to achieve abstraction (Link to my blog). Let's give an example of the Object.create method as follows.

var Logger = { log : function(log){} } 
var ConsoleLogger = function() {}; 
ConsoleLogger.prototype = Object.create(Logger);

I believe it's just a matter of setting the prototype of the specific piece constructors to an instance of Piece . For example:

Pawn.prototype = new Piece("", false, false);

However, this will not call the Piece (super) constructor every time you instantiate a new Pawn , so you'll have to manually assign color, type, etc. from the Pawn constructor:

-- EDIT --

You might prefer this instead: Javascript inheritance: call super-constructor or use prototype chain?

If you are willing to take an object oriented approach on JS I would recommend you to follow the power constructor pattern.

Basically you have a function that creates objects for you and take advantage of the closures to hide the internal properties (fields or methods).

 function myObject(){
    var that={};
    var myPrivateField;
    var myPrivateFunction=function(){
    }

    that.myPublicMethod=function(){

    }
    return that;

    }

Then you can just call the method myObject() and you will get a new object of this type.

You can extend this example to use inheritance by just calling the power constructor of another object and then use object augmentation. Take a look at the example of parasatic inheritance of Douglas Crockford.

You can call Piece 's constructor from Pawn and have that constructor operate on the Pawn instance:

function Pawn(/* args... */) {
    Piece.call(this, color, type, captured, hasMoved);
    /* Pawn-specific constructor code... */
}

Take a look at this: https://github.com/haroldiedema/joii

var BaseClass = function() 
{
    this.some_var = "foobar";

    /**
     * @return string
     */
    this.someMethod = function() {
        return this.some_var;
    }
};

var MyClass = new Class({ extends: BaseClass }, function()
{
    /**
     * @param string value
     */
    this.__construct = function(value)
    {
        this.some_var = value;
    }

})

Usage:

var obj = new MyClass("Hello World!");
console.log( obj.someMethod() ); // Hello World!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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