Backbone.js 在主干.Model中使用u.bindAll

Backbone.js 在主干.Model中使用u.bindAll,backbone.js,this,underscore.js,Backbone.js,This,Underscore.js,我仍然很困惑如何使用。我知道,这个有时指的是另一个对象,因此我们需要使用\uu.bindAll()来纠正它 例如,在这里我不能使用this.setLevelTimer(false),因为this指向setTimeout,所以我应该将.bindAll()放在哪里 如果有多个实例此指向不正确,该怎么办。我是否使用了多个\uu.bindAll()s var model=Backbone.model.extend({ 初始化:函数(){ } ... setLevelTimer:函数(){ if(δ

我仍然很困惑如何使用。我知道,这个有时指的是另一个对象,因此我们需要使用
\uu.bindAll()
来纠正它

例如,在这里我不能使用
this.setLevelTimer(false)
,因为
this
指向
setTimeout
,所以我应该将
.bindAll()
放在哪里

如果有多个实例
指向不正确,该怎么办。我是否使用了多个
\uu.bindAll()
s

var model=Backbone.model.extend({
初始化:函数(){
}
...
setLevelTimer:函数(){
if(δ<0){
这是gameOver();
}否则{
gameState.timer=setTimeout(函数(){
返回此值。setLevelTimer(false);/“此”无效
}, 30);
}
}
...
});

..bindAll将this对象绑定为函数作用域的初始化对象

如果在函数中有嵌套作用域,则此对象可能不同

比如说

setLevelTimer: function(){
  // this should equal to the initialized model
  $("a").click(function(){
    // the this variable here is the clicked DOM object - not the initialized model
  });
}
此问题的常见解决方案是在函数的第一行设置该变量,然后您也可以在嵌套范围内使用它(当然,只要不重新定义它),例如:

setLevelTimer: function(){
  // this should equal to the initialized model
  var that = this;
  $("a").click(function(){
    // the that variable here is the initialized model
  });
}

.bindAll
将给定对象的函数属性“
绑定到给定对象

您所做的是假设在您提供给
setTimeout
的匿名函数中正确设置了
,但这怎么可能,因为匿名函数不是您模型的函数属性

这就是为什么必须为匿名函数提供正确的
This
,至少有以下两种方法:

var self = this; // store correct this into a variable
gameState.timer = setTimeout(function(){
     return self.setLevelTimer(false); 
}, 30);

希望这对你有所帮助(并为你扫清障碍)

附言


至于回答你原来的问题。此问题不是
.bindAll
的错误,您应该在
初始化
-函数中使用
.bindAll(This)
,以将主干对象的函数绑定到正确的
This
,但由于bindAll不会影响您动态创建的匿名函数,因此需要使用其他措施(我在上面描述了其中一些)要将它们绑定到您想要的
这个

我理解这一部分,所以说上面的
返回这个。setLevelTimer
,我该如何更正
这个
。我会在
setLevelTimer
函数的开头使用
.bindAll
吗?我试过了,但没有成功。谢谢。上面只是一些例子我有随机代码。但我从你的例子中了解到如何避免这种问题。
var self = this; // store correct this into a variable
gameState.timer = setTimeout(function(){
     return self.setLevelTimer(false); 
}, 30);
// use bind to bind your anonymous functio to the right this
gameState.timer = setTimeout(_.bind(function(){ 
   return this.setLevelTimer(false); 
}, this), 30);