遇到一个setTimeout的问题,setTimeout("xxx()",2000)中,会发生找不到xxx()函式的问题,Google了一下,发现有解法,后来用setTimeout(function(){xxx()},2000)的方式解决了,但是为什么用匿名函式它就找得到,还是有点想不通,先把网路寻得的解决备份起来,待日后慢慢琢磨。
var Obj = function(msg){ this.msg = msg; this.shout = function(){ alert(this.msg); } this.waitAndShout = function(){ // 隔五秒钟后执行上面的 shout 方法 } } var testObj = new Obj("Hello,World!"); testObj.shout();
坦白的说,之前我并没有在 Javascript 类中使用 setTimeout/setInterval 的经验,所以开始就很草率的认为这是无法实现的。但是经过深思熟虑以后发现是可以实现的。退一步说,隔五秒执行某段语句是非常容易实现的。比如不考虑别的因素,题目中的函数是可以这样写:
this.waitAndShout = function(){ setTimeout('this.shout()', 5000); }
在运行以后,谁都会意识到 this 这个变数是无法找到的。但是这是为什么呢,很快就可以意识到,其实 setTimeout/setInterval 是 window 物件的一个方法,所以也可以写成 window.setTimeout/window.setInterval,那么上述的 this.shout() 就非常可以容易理解为什么不能执行了,因为它实际上调用的是 window.shout() 。
知道了原因以后解决起来就非常的容易了,只要将物件绑定到 window 物件下就可以(我对 Javascript 有趣的物件机制感到兴奋)。那么,上述的函数再做一个小的修改:
this.waitAndShout = function() { window.Obj = this; setTimeout('Obj.shout()', 5000); }
这样就可以了。实际上
setTimeout('Obj.shout()', 5000);
等价于
window.setTimeout('window.Obj.shout()', 5000);
(中略...)
...还有另外的一个办法就是通过 Closure(闭包) 来实现,代码如下:
var Obj = function(msg){ this.msg = msg; this.shout = function() { alert(this.msg); this.waitAndShout(); } var _self = this; this.waitAndShout = function() { setTimeout(function(){_self.shout()}, 5000); } } var testObj = new Obj("Hello,World!"); testObj.shout();