通过简单的Backbone示例了解javascript这个范围

时间:2012-05-02 07:13:52

标签: javascript backbone.js closures this

查看this jsFiddle

代码也列在下面:

window.MyView = Backbone.View.extend({

ticks: 0,
initialize: function() {
    //window.setInterval(this.onTimerTick, 1000); // arghhh.. can't understand the 'this' scoping       
    window.setInterval(this.onTimerTick2, 1000);  // Works great with globals       
},

render: function() {
    this.$el.text(this.ticks);            
},

onTimerTick: function() {  // Trouble with this
    this.ticks++;
    this.render();
},

onTimerTick2: function() {  // Using globals
    window.ticks2++;
    $('#count').text(window.ticks2);
}
});

window.My = new MyView({ el: $("#count") });
window.ticks2 = 0;

查看代码,你会发现我想使用onTimerTick函数,但是因为我无法弄清楚如何从窗口获取 - 这就是My-this,我必须使用onTimerTick2中的方法。 (通常我会使用那个=这个,但在这种情况下还不够)

感谢任何有意义的让我明白这一点(!)

由于

Larsi

3 个答案:

答案 0 :(得分:2)

this.onTimerTick2传递给setTimeout时,将调用该函数,this绑定到全局对象,而不是对象。

如果underscore.js可用(根据@ori),您可以使用_.bind()在调用时将this锁定到正确的对象:

window.setInterval(_.bind(this.onTimerTick, this), 1000);

以下是一些不依赖于库的解决方案:

// Works in all browsers
var self = this;
window.setInterval(function() {
    self.onTimerTick();
}, 1000);

使用现代JS引擎,您还可以使用Function.bind()来保持正确的this

// Requires a modern JS engine
window.setInterval(this.onTimerTick.bind(this), 1000);

答案 1 :(得分:0)

看起来骨干使用下划线的bind函数,所以:

 window.setInterval(_.bind(this.onTimerTick2, this), 1000); 

答案 2 :(得分:0)

您还可以依赖_.bindAll实用程序方法,以保持代码清洁和可重用。

initialize: function() {
    _.bindAll(this, 'myFunction')
    setInterval(this.myFunction, 1000)
},

myFunc: function() {
    console.log(this)
}