James Dawson
James Dawson

Reputation: 5409

Accessing object properties from object itself

I'm having a little trouble learning object-oriented Javascript. I have two classes called Cosmos and Background, Cosmos looks like this:

// js/Cosmos.js
function Cosmos() {
    this.background = new Background();

    // Fire game loop
    this.ticker = setInterval(this.tick, 1000 / 60);
}

// Main game loop
Cosmos.prototype.tick = function() {
    console.log(this.background);
}

When the main game loop ticks, I get undefined in console. I don't quite understand this because this.background is a property of the Cosmos class, so it should be accessible by the methods defined in the Cosmos class, no?

If I go back to my index.html page's script tag and change it to this:

// Lift off
var cosmos = new Cosmos();
console.log(cosmos.background);

it works and the Background object gets logged to the console. Can anyone offer an explanation and tell me how I can access the properties of Cosmos from within Cosmos.tick?

Edit: Turns out the problem is something to do with setInterval(), because if I do this the proper object is logged to console:

function Cosmos() {
    this.background = new Background();

    // Fire game loop
    //this.ticker = setInterval(this.tick, 1000 / 60);
    this.tick();
}

// Main game loop
Cosmos.prototype.tick = function() {
    console.log(this.background);
}

still don't know the best way around it, though.

Upvotes: 0

Views: 88

Answers (2)

Explosion Pills
Explosion Pills

Reputation: 191749

this in function scope for setInterval is window, but you can change function scope via .bind (or just redeclare this like the other answer says):

this.ticker = setInterval(this.tick.bind(this), 1000 / 60);

http://jsfiddle.net/ExplosionPIlls/SwQ5V/

Upvotes: 0

KaeruCT
KaeruCT

Reputation: 1645

When the function is called from setInterval, this will not be bound to the object anymore.

This is a quick fix to your problem:

// js/Cosmos.js
function Cosmos() {
    var self = this;
    this.background = new Background();

    // Fire game loop
    this.ticker = setInterval(function () {
        self.tick();
    }, 1000 / 60);
}

By using the self variable, the inner function gets to access this.

Upvotes: 2

Related Questions