0

When I try access to the object with "this" keyword, I am getting the "window" object instead of object's itself because I bind it's function to an event and that event belongs to window object.

In the example, alert(this.osd) says that it is undefined because there is no "osd" in the "window" object. So, what is the best way to solve this ? Defining the game object as window.game ?

var game = {

    osd : null,
    stage : null,

    tick : function(){
        alert(this.osd);

    },

    init : function(){

        // Configure the OSD
        this.osd = "a";

        // Preapare the stage;
        this.stage = "b";
        window.addEventListener("click",this.tick);
    }
}

game.init();
Tim
  • 699
  • 8
  • 27

2 Answers2

3

You need to call the tick method with the object context like this:

var self = this;
window.addEventListener("click", function() {self.tick()});

Or, you could use .bind() in modern browsers which does essentially the same thing (it creates a stub function that calls the actual method with the right object context).

window.addEventListener("click", this.tick.bind(this));

The issue is that when you pass this.tick to addEventListener(), you are only passing a function reference to the tick function, you aren't actually passing the object reference. So, when addEventListener() calls tick without any object reference, the default value of this for a function call without an object reference is window (when not in strict mode) so that's what you're seeing.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
-1

You can bind using a closure, like this:

window.addEventListener('click',(function(o){return function(){o.tick()}})(this));

Also, (unrelated to your problem), since you're making an initialiser function, you would be better off using a class/instance setup:

function Game( myParameter ) {
    this.osd = "a";
    this.tick = function( ) {
    }
    window.addEventListener('click',(function(o){return function(){o.tick()}})(this));
}
var game = new Game( 3 );

Notice that game is now created with new, and we can pass parameters to its "constructor" function.

Dave
  • 44,275
  • 12
  • 65
  • 105
  • "`game` is not a true object in that code" yes it is. It's declared with an object literal. – zzzzBov Mar 30 '13 at 03:18
  • game is too a real object with methods. – jfriend00 Mar 30 '13 at 03:19
  • @zzzzBov et al. Yes, ok. I missed the problem (now edited). It isn't a real object though (as far as OOP goes); prototype definitions need the `new` keyword, for example. – Dave Mar 30 '13 at 03:23
  • Objects can be created with a static declaration too just like the `game` object in the OP's code. You seem to be under the false impression that a statically declared object isn't a real object. That's just wrong. – jfriend00 Mar 30 '13 at 03:28
  • @jfriend00 I know it's an object, and will function perfectly well in this case, but (in my opinion) it's a bad practice, because it is *not* an OOP object. It doesn't conform to the standard class/instance setup, and will not support prototypes. – Dave Mar 30 '13 at 03:33
  • @jfriend00 taking what you said into account, I have adjusted the language of my comments. – Dave Mar 30 '13 at 03:38