任何人都可以告诉我为什么这不起作用吗?
(function() {
window.Test = {};
})();
Test.Timers = {
c: null,
startTimer: function() { c = 0; setTimeout(this.doWork, 0); },
doWork: function() {
c++;
alert(c);
setTimeout(this.doWork, 0);
}
};
当我调用Test.Timers.startTimer()时,它只用1警告一次。 感谢
答案 0 :(得分:1)
方法不会“记住”其所有者(其this
);您可以将方法从一个对象复制到另一个对象,并将其视为任何其他函数。当您使用点符号实际调用它时,它只有正确的所有者,例如this.doWork()
。
所以你的问题是你将函数this.doWork
传递给setTimeout
,然后在不知道其所有者的情况下将其作为函数调用,突然它this
为{{{ 1}}而不是你的计时器对象。要解决此问题,您需要自己跟踪window
。例如,您可以写:
this
或:
Test.Timers = (function () {
var newTimer = {
c: null,
startTimer: function() {
this.c = 0;
setTimeout(function () { newTimer.doWork(); }, 0);
},
doWork: function() {
this.c++;
alert(this.c);
setTimeout(function () { newTimer.doWork(); }, 0);
}
};
return newTimer;
})();
(请注意,我还在必要时将Test.Timers = (function () {
var startTimer = function() {
newTimer.c = 0;
setTimeout(doWork, 0);
};
var doWork = function() {
newTimer.c++;
alert(newTimer.c);
setTimeout(doWork, 0);
};
var newTimer = {
c: null,
startTimer: startTimer,
doWork: doWork
};
return newTimer;
})();
更改为c
或this.c
,因为您的版本重复提到newTimer.c
。另请注意,在第二个版本中,如果您不需要外部代码就可以访问window.c
,您可以将其更改为本地变量,使事情更清晰。)
答案 1 :(得分:0)
根据您对Ruakh答案的评论,我更喜欢以下方法,我自己:
Test.Timers = (function () {
var this_ = {
c: null,
startTimer: function() { this_.c = 0; setTimeout(this_.doWork, 0); },
doWork: function() {
this_.c++;
alert(this_.c);
setTimeout(this_.doWork, 0);
}
};
return this_;
})();
这样,意思很清楚,因为this_
看起来像this
,而你所要做的就是习惯于制作匿名函数并立即调用它的闭包模式。另请注意,我修改了对c
的引用,以引用this_.c
而不是全局变量c
。
或者,您可以使用.bind()
将函数的this
绑定到特定的东西。这至少是Chrome的V8内置,也可能是Firefox:
Test.Timers = {
c: null,
startTimer: function() { this.c = 0; setTimeout(this.doWork, 0); },
doWork: function() {
this.c++;
alert(this.c);
setTimeout(this.doWork, 0);
}
};
Test.Timers.startTimer = Test.Timers.startTimer.bind(Test.Timers);
Test.Timers.doWork = Test.Timers.doWork.bind(Test.Timers);