Avner
Avner

Reputation: 61

Array of objects in JS

I am a JS newbi am trying to create an Array of objects. I have created the following object:

gameCard = new Object({
    image : "",
    container:"",
    match2Card:"",
    visible: false,
    cardId:"",

    updateCard: function (imageName,divName,matchingCard,isVisible,cardId) {
        this.image = imageName;
        this.container = divName;
        this.match2Card = matchingCard;
        this.visible = isVisible;
        this.cardId = cardId;
    },
    toggleCard: function (){
        if (this.visble) {
            this.visble = false;
        }
        else {
            this.visble = true;
        }
    },
    printCard : function() {
        document.write (this.image + ' ' + this.container + ' ' + this.match2Card + ' ' + this.visible + ' ' + this.cardId + '<br>') ;
        //alert (this.match2card);
    }
})

and run the following :

gameCards = new Array ();

for (i=0; i<20 ; i=i+1) {
    z=i+1;

    c1 = Math.floor((Math.random()*20)+1);

    gameCard.updateCard ( 'images/bf'+i+'.jpg' , 'div' + c1 , z , false,i) ;

    gameCards.push(gameCard);
}

when printing the array by using :

for (i=0;i<20; i++) {
    gameCards[i].printCard();
}

all items are the same.

what am I doing wrong ?

Upvotes: -1

Views: 164

Answers (2)

pete
pete

Reputation: 25081

Either define your GameCard object like so (fiddle):

var GameCard = function () { //wrap in a function to mimic a constructor
    return {
        "image": "",
        "container": "",
        "match2Card": "",
        "visible": false,
        "cardId": "",
        "updateCard": function (imageName, divName, matchingCard, isVisible, cardId) {
            this.image = imageName;
            this.container = divName;
            this.match2Card = matchingCard;
            this.visible = isVisible;
            this.cardId = cardId;
        },
        "toggleCard": function () {
            this.visible = !this.visible;
        },
        "printCard": function () {
            log(this.image + ' ' + this.container + ' ' + this.match2Card + ' ' + this.visible + ' ' + this.cardId + '<br>');
        }
    };
};

var test = function () {
    var gameCards = [],
        card = null,
        i = 0;
    for (i = 0; i < 20; i = i + 1) {
        // call the function to get a new object
        card = GameCard();
        // set object properties
        z = i + 1;
        c1 = Math.floor((Math.random() * 20) + 1);
        card.updateCard('images/bf' + i + '.jpg', 'div' + c1, z, false, i);
        // push into array
        gameCards.push(card);
    }
    for (i = 0; i < 20; i++) {
        gameCards[i].printCard();
    }
};
test();

or define it like this (fiddle):

var GameCard = function () { //or make a constructable object
    this.image = "";
    this.container = "";
    this.match2Card = "";
    this.visible = false;
    this.cardId = "";
    this.updateCard = function (imageName, divName, matchingCard, isVisible, cardId) {
        this.image = imageName;
        this.container = divName;
        this.match2Card = matchingCard;
        this.visible = isVisible;
        this.cardId = cardId;
    };
    this.toggleCard = function () {
        this.visible = !this.visible;
    };
    this.printCard = function () {
        log(this.image + ' ' + this.container + ' ' + this.match2Card + ' ' + this.visible + ' ' + this.cardId + '<br>');
    };
};

var test = function () {
    var gameCards = [],
        card = null,
        i = 0;
    for (i = 0; i < 20; i = i + 1) {
        // instantiate new object
        card = new GameCard();
        // set properties
        z = i + 1;
        c1 = Math.floor((Math.random() * 20) + 1);
        card.updateCard('images/bf' + i + '.jpg', 'div' + c1, z, false, i);
        // push into array
        gameCards.push(card);
    }
    for (i = 0; i < 20; i++) {
        gameCards[i].printCard();
    }
};
test();

Otherwise, what you're doing is pushing the same instance into the array 20 times.

UPDATE

You could also define your GameCard object as you're currently doing and then call Object.create(GameCard) to create a new instance of it (fiddle):

var GameCard = {
    "image": "",
    "container": "",
    "match2Card": "",
    "visible": false,
    "cardId": "",
    "updateCard": function (imageName, divName, matchingCard, isVisible, cardId) {
        this.image = imageName;
        this.container = divName;
        this.match2Card = matchingCard;
        this.visible = isVisible;
        this.cardId = cardId;
    },
    "toggleCard": function () {
        this.visible = !this.visible;
    },
    "printCard": function () {
        log(this.image + ' ' + this.container + ' ' + this.match2Card + ' ' + this.visible + ' ' + this.cardId + '<br>');
    };

var test = function () {
    var gameCards = [],
        card = null,
        i = 0;
    for (i = 0; i < 20; i = i + 1) {
        // use Object.create for a constructor
        card = Object.create(GameCard);
        // set properties
        z = i + 1;
        c1 = Math.floor((Math.random() * 20) + 1);
        card.updateCard('images/bf' + i + '.jpg', 'div' + c1, z, false, i);
        // push into array
        gameCards.push(card);
    }
    for (i = 0; i < 20; i++) {
        gameCards[i].printCard();
    }
};
test();

Upvotes: 1

Thierry
Thierry

Reputation: 5233

You are using only one object, you must use

gameCard = {…} in the loop. (new Object is not necessary)

for (var i = 0; i < 20; ++i) {
   var gameCard = {…}; // create a new instance of object
   …
}

Upvotes: 1

Related Questions