开发者

Propogation of *this* in nested function calls in Backbone.js

I started using backbone.js recently for a game. I used model to create Timer as follows:

var Timer = Backbone.Model.extend({
    defaults: {
        'hh':00, 'mm':05, 'ss':00
    },

    initialize: function() {
    },

    countDownOnce: function() {
         // Count down the time by 1 sec
    },

    run1: function() {
        this.countDownOnce();
    }

    run开发者_高级运维2: function() {  
        setInterval(this.countDownOnce, 1000);  
    }  
});

The countDownOnce function, if called directly as in run1, works fine.

But if the function is passed as an argument to some built-in function, say setInterval as in the run2 function, the value of this is lost.

How to propagate this pointer to the built-in functions?


The Backbone docs have a useful section on binding "this".

Basically, Underscore provides a couple of very useful functions, _.bind and _.bindAll, which help you more easily manage 'this's context.

...

initialize: function() {
  _.bindAll(this, 'countDownOnce' //, and whatever other functions you want bound)
}),

...

This will make sure that no matter what context it's called from, the 'this' inside countDownOnce refers to your Timer instance.


One way to do this is using call and apply. For example:

run2: function() {  
    setInterval(this.countDownOnce.call, 1000, this);  
}

Also note that passing a closure/function reference with arguments to setTimeout() and setInterval() requires some manual hacks to work correctly in IE.


this is how javascript was designed (pun intended :)

Basically 'this' binds to the current context so if in a function/method call like this:

var Data = function(name) {
   this.name = name;
}

var myData = new Data("viky");

would refer to the name element "inside" Data (i.e., myData in this case)

Now if you had the following:

var Data = function(name) {

function morphName(anotherName) {
  //and if you call this like this ;)
   alert(this.name); //undefined
  }

}

the inner function morphName is bound to the 'current' context i.e., the outer function. In javascript everything is an object, including functions. So the outer (anonymous) function doesn't have a member called name! (makes sense?)

In order to do that most people use the following (by convention):

var Data = function(name) {

var that = this; //capture current context. Some prefer self = this;

function morphName(anotherName) {
  //then you access name like that ;)
   alert(that.name);
  }

}

I suggest you read about javascript closures and scopes to understand this and that :D

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜