2012-05-02 50 views
2

看看this jsFiddle瞭解JavaScript本作用域用一個簡單的骨幹例如

守則還列出如下:

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功能,但因爲我無法弄清楚如何從窗口 - 這到我 - 這,我必須使用onTimerTick2中看到的方法。 (通常我避開了那個=這一點,但在這種情況下,它是不夠的)

感謝任何attemt讓我明白這個(!)

感謝

Larsi

回答

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); 
+0

不是我!我很高興所有的建議:-)感謝您提供一個很好的答案 – Larsi

+0

從@MichalB的一個是我,因爲它看起來很錯誤 – ThiefMaster

0

看起來骨幹網使用的bind功能的下劃線,所以:

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

您也可以依靠於_.bindAll實用的方法,以保持代碼更加清晰和可重複使用的。

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

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