Javascript 尽管使用了.bind(this),但它仍然引用全局对象
对于如何将Javascript 尽管使用了.bind(this),但它仍然引用全局对象,javascript,Javascript,对于如何将此与绑定结合使用,我感到困惑。我知道问题源于这个是全局对象。有人能解释一下我是如何规避的吗 在构造函数中,我完成了以下操作: var BoundedStartTimer = this.StartTimer.bind(this); var BoundedStopTimer = this.StopTimer.bind(this); var BoundedClearTimeString = this.ClearTimeString.bind(this); BoundedClearTimeSt
此
与绑定
结合使用,我感到困惑。我知道问题源于这个是全局对象。有人能解释一下我是如何规避的吗
在构造函数中,我完成了以下操作:
var BoundedStartTimer = this.StartTimer.bind(this);
var BoundedStopTimer = this.StopTimer.bind(this);
var BoundedClearTimeString = this.ClearTimeString.bind(this);
BoundedClearTimeString();
最后一个可以工作,但是当我调用BoundedStartTimer()时计时器不会启动代码>
我不知道我在做什么。以下是我的声明:
MemoryGame.prototype.StartTimer = function(){
var playTimeInMilliseconds = 0;
this.timeString = "";
this.timer = window.setInterval(function(){
if(playTimeInMilliseconds >= 1000)
this.timeString = .....
this.handleToTimerText.textContent = this.timeString;
}, 10);
}
MemoryGame.prototype.StopTimer = function(){
clearInterval(this.timer);
}
MemoryGame.prototype.ClearTimeString = function(){
this.handleToTimerText.textContent = "00:000";
}
这里的问题是您的setInterval
调用setInterval
在全局范围内执行函数,这意味着this===window
并不理想。您是对的,bind
可以在这里工作,只需将间隔回调绑定到this
:
window.setInterval(function(){
if(playTimeInMilliseconds >= 1000)
this.timeString = .....
this.handleToTimerText.textContent = this.timeString;
}.bind(this), 10);
// ^ bind this from your MemoryGame instance to the interval callback
这就是交易
每次你看到关键字函数
,你应该考虑两件事
第一个是,“哦,这为变量创建了一个新的作用域!”许多Java用户认为,每个没有用作对象文字的大括号都会发生这种情况;这是错误的,它只是一个函数上下文(或者,现在在ES6中,也有let
和=>
这样做。)
第二件事是,“哦,可能这个
和参数
在新的变量范围内会有所不同。”这是因为这两个关键字在JavaScript中特别“神奇”
所以当你写作时:
this.timer=window.setInterval(函数(){
如果(播放时间毫秒>=1000){
this.timeString=。。。。。
}
this.handleotimertext.textContent=this.timeString;
}, 10);
…您必须将
函数
视为一个新的变量范围,它有自己的此
和参数
现在,playtimeinmillides
将是好的,如果您不在该函数的任何时候写入var playtimeinmillides
,它将被“提升”到函数声明的顶部,并声明该作用域的本地新变量。只要您从未这样做,playtimeinmillizes
将查看父变量作用域并找到您在外部作用域中定义的变量
但是,this.timeString
和this.handleToTimerText
不是很好,因为this
的值被声明为window
有两种补救方法:
在外部函数中,将this
捕获到您自己的变量中。用于此目的的常见变量名称是me
和self
。只需在外部函数中写入var self=this;
,然后在内部函数中写入var self
,然后写入self.timeString
和self.handleToTimerText
获取函数并显式地.bind()
它。因此,像这样拉出函数:
函数updateTimerText(){
如果(播放时间毫秒>=1000){
this.timeString=。。。。。
}
this.handleotimertext.textContent=this.timeString;
}
this.timer=setInterval(updateTimerText.bind(this),10);
显然,bind
有很大的威力!所以不要做这样的废话:
var BoundedStartTimer=this.StartTimer.bind(this);
var BoundedStopTimer=this.StopTimer.bind(this);
var BoundedClearTimeString=this.ClearTimeString.bind(this);
BoundedClearTimeString();
我不知道这个东西发生在什么范围内,但它可能不在正确的范围内。因为无论绑定为this
,都必须是您创建的new MemoryGame()
的实例——可以说您将其称为var myMemoryGame=new MemoryGame()
左右;只要使用myMemoryGame.startTimer()
(或其他)让这个
自然出现。每当你在函数e()的上下文中编写a.b.c.d.e()
这个
被神奇地设置为a.b.c.d
。除非你知道你在做什么,并且你必须在新的上下文中保存这个
。至少要善待读者和.bind(MyMemoryName)
这样它就100%清晰了。谢谢@Travis J.计时器启动了。但是为什么BoundedStopTimer()没有呢停下来?@LasseKaragiannis你能用完整的JS代码创建一个吗?这会使测试更容易。@Xufox谢谢,但我对网络编程不太熟悉,我真的不知道怎么做。我使用的是实验室里的一个流浪服务器。我在pastebin上构建了一个示例代码,带有一个按钮和一个span元素,只是为了让一些东西能够协同工作ncrete将围绕绑定的“this”问题展开讨论。它向DOM中添加了一个按钮和一个span元素。单击按钮时,span元素的文本内容将“递增”,计数秒,当再次单击按钮时,计时器停止。@LasseKaragiannis Hm,好的,我实际上只是想测试MemoryGame.prototype.StopTimer
函数中的这个
是什么 — 全局对象或所需对象。因为this.timer
可能是未定义的
,如果此
引用了错误的对象,则生成的clearInterval(未定义)
什么也不做。我没有得到所有的东西。英语,对我来说并不总是很清楚…你能试着解释一下,为什么BoundedClearTimeString();有效,但这个.StopTimer()或BoundedStopTimer()都无效;如果BoundedClearTimeString()
有效,但BoundedStopTimer(),非常有用
没有,那么问题不在于此范围。您可能应该检查控制台中的代码错误。可能没有错误:例如,在t