Struggling with Prototypes/Inheritance in JavaScript

100 views Asked by At

I have a little practice project, where I am developing a Blackjack Game. I am using JS prototypes for OOP purposes, which works great so far. I have a Game, Card and Hand (all the cards a player has) prototype object. Now I have a problem with my Hand prototype. It returns my card values "undefined". I don't know what is wrong since my Hand constructor returns the right values.

I have to admit my understanding of JS prototypes is maybe not the best yet, so this might be my problem which I am struggling with?!

This is the relevant snippet from my code:

var suits = ["club", "diamond", "heart", "spade"];
var cardValue = ["ace", 2, 3, 4, 5, 6, 7, 8, 9, "jack", "queen", "king"];

function Game() {
}

Game.prototype = {

    deal: function() {
        var cardSuit = Math.floor(Math.random() * suits.length);
        var cardNumber = Math.floor(Math.random() * cardValue.length);

        return cardSuit, cardNumber;
    },


    createHand: function() {
        var newHand = new Hand();
        var userCards = newHand.getHand();

        return newHand;
    }

};

var card1, card2, handCards;

function Hand() {
    var card1 = Game.prototype.deal(); //works! return two values
    var card2 = Game.prototype.deal(); //works! return two values
    var handCards = [card1, card2]; //works! creates array from card 1 and 2
}

Hand.prototype = {

    getFirstCard: function() {
        return card1; // IS "UNDEFINED"!
    },

    getSecondCard: function() {
        return card2; // IS "UNDEFINED"!
    },

    getHand: function() {
        return handCards; // IS "UNDEFINED"!
    }
};

Can you please help me? Thank you very much in advance!

1

There are 1 answers

5
nnnnnn On BEST ANSWER

You are declaring some global variables without assigning values:

var card1, card2, handCards;

Then in hour Hand() function you declare variables of the same name that are local to that function:

function Hand() {
    var card1 = Game.prototype.deal();
    // etc.

Then your other functions try to access the globals which have never been assigned a value:

getFirstCard: function() {
    return card1; // IS "UNDEFINED"!
},

If you want to access these values from the methods of your "class" these variables should be instance variables:

function Hand() {
    this.card1 = Game.prototype.deal(); //works! return two values
    this.card2 = Game.prototype.deal(); //works! return two values
    this.handCards = [this.card1, this.card2]; //works! creates array from card 1 and 2
}
...
getFirstCard: function() {
    return this.card1;
},

...and so forth in the other methods that use those variables. And you can delete the var card1, card2, handCards; line.

Or it might be tidier to do this:

function Hand() {
    this.handCards = [Game.prototype.deal(), Game.prototype.deal()];
}
...
getFirstCard: function() {
    return this.handCards[0];
},
getSecondCard: function() {
    return this.handCards[1];
},

(There are other problems in your code, e.g.:

  • your cardValue array is missing 10
  • return cardSuit, cardNumber; will just return cardNumber
  • your createHand() function declares and sets a userCards variable that is never used
  • I don't see the point in having a Game() constructor if you never instantiate any Game objects and just call the methods of the prototype like Game.prototype.deal()
  • you don't keep track of what cards are left in the deck, so (however unlikely) the random card selection could deal the same card twice

...and so forth.)