0

I'm currently writing a Scene structure for a game I'm making in javascript with the createjs framework. The problem I'm running into is properly referencing the original class in the prototypal functions. I'm relatively new to javascript and this is the first time I've had to use prototype. My current code is as follows:

function Intro(p, c){
    this.parent = p;
    var s = new createjs.Stage(c);
    this.stage = s;

    this.queue = new createjs.LoadQueue(false);
    this.queue.installPlugin(createjs.Sound);
    this.queue.addEventListener("complete", this.handleComplete);
    this.queue.loadManifest([{id:"bg", src:"images/Intro/intro_background.png"}]);
}
Intro.prototype.handleComplete = function(event){
    console.log("queue completed - handling...");
    var q = event.target;
    var bg = new createjs.Bitmap(q.getResult("bg"));
    this.stage.addChild(bg);
    this.stage.update();
}

When I get to

this.stage.addChild(bg);

it appears to lose scope and I get "cannot call method 'addChild' of undefined.

Any help would be greatly appreciated! -xv

2 Answers2

0

You can fix your scope problem by changing

this.queue.addEventListener("complete", this.handleComplete);

to

this.queue.addEventListener("complete", this.handleComplete.bind(this));

so that the scope of the bound function is this.

BTW, you might be interested by my game in which I override createjs classes ( https://github.com/Canop/SpaceBullet/tree/master/src ). I think I handled this problem in a clean way.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
0

If you invoke function in JS, it'll be bound dynamically. What value will be bound to the this depends on the way you invoke it, whether function is called as a constructor and whether your code is running in strict mode.

In your case, the following line:

this.queue.addEventListener("complete", this.handleComplete);

makes your function to run with this bound to the global object (in the web browser, global object is a window object) or, if in strict mode, this will be undefined.

As @dystroy suggested, use bind() method to change this behaviour. Calling:

this.queue.addEventListener("complete", this.handleComplete.bind(this));

causes binding this inside the handleComplete() to the same this as in Intro.


If you want to understand it in more detail. I strongly suggest reading Dmitry Soshnikov's blog.

kamituel
  • 34,606
  • 6
  • 81
  • 98