1

I’m building a card game in JavaScript in order to increase my web programming chops, and I’m having an issue with JavaScript Prototype inheritance. My design has a base Card class that contains all of the function and data any card will ever need. The design itself is relatively flexible, so just by changing the data stored about 25% of cards can use the base class. What I need to do is create new classes that inherits everything from Card – including the data – but overrides a small subset of the available functions without touching the base class functions.

I’ve been attempting to use prototype inheritance to accomplish this, but this changes the base class, which not only screws up any cards using the Card class, but also every other function that inherits from the base class.

What I need is a design pattern that allows me to override a function ONLY for the classes inheriting from Card. Is this possible in JavaScript?

Edit...

Sorry, here's an example, probally should have added this in the first place.

Starting with the Base Card class.

function Card(){
    this.cardID = 0;
    this.name = '';
    this.imageID = 0;
    this.imageURL = '';
    this.imageAlt = '';
    etc....
}

Card.prototype.init = function( inID
    , inName
    , inImageID
    , inImageURL
    , inImageAlt
    , inImageHorizontal
    etc...
){
    this.cardID = inID;
    this.name = inName;
    this.imageID = inImageID;
    this.imageURL = inImageURL;
    this.imageAlt = inImageAlt; 
}

Card.prototype.whenPlayed = function(){
    return false;
}

Now my Child Class:

ChildCard.prototype = new Card();
ChildCard.constructor = ChildCard;
function ChildCard(){};

ChildCard.prototype.whenPlayed = function(){
    alert("You Win!");
    return true;
}

As it stands now if I were to create a Card object and call its whenPlayed I'd get the behavior from ChildCard not Card.

The issue I'm really facing here is the card class has approaching 3 donzen methods, and I don't want to have to define each one in each child class.

  • 1
    Sounds like you want Simple JavaScript Inheritance http://ejohn.org/blog/simple-javascript-inheritance/ – QuentinUK Feb 26 '13 at 20:20
  • @QuentinUK: No. That wont help understanding the issues. – Bergi Feb 26 '13 at 20:23
  • probably the same issue as in [Why can't I call a prototyped method in Javascript?](http://stackoverflow.com/questions/12500637/why-cant-i-call-a-prototyped-method-in-javascript) – Bergi Feb 26 '13 at 20:24
  • Please show an example of what you're currently doing, otherwise we can only guess what's going wrong. – bfavaretto Feb 26 '13 at 20:36
  • The code you posted does not exhibit the behavior you describe: http://jsfiddle.net/42PVM/. – Felix Kling Feb 26 '13 at 23:48

1 Answers1

8

A quite simple and straightforward pattern:

function Parent(arg) {
    this.someProperty = arg;
    // initialize all instance properties in the constructor
}


// The prototype should only contain methods and primitive values.
Parent.prototype.someMethod = function() {
    // ...
};

Parent.prototype.someOtherMethod = function() {
    // ...
};


function Child(arg1, arg2) {
    // call parent constructor -- like super() in other languages
    Parent.call(this, arg1);
    // initialize all instance properties in the constructor
}

// Hook up Base.prototype into the prototype chain
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child; // not necessary but can be useful

Child.prototype.someMethod = function() {
   // override method and call parent method
   Base.prototype.someMethod.call(this);
   // ...
};

It relies on Object.create [MDN]. It creates a new object which inherits from the passed in object. So you get one level of indirection between Child.prototype and Parent.prototype, i.e. changes to Child.prototype don't influence `Parent.prototype.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143