JavaScript学习之setTimeout
《JavaScript权威指南》第四版中说“window对象方法setTimeout()用来安排一个JavaScript的代码段在将来的某个指定时间运行”。
setTimeout(foo,i); // foo是回调函数,i是延时时间
注意“将来”一词,setTime会把foo函数放到队列中,当线程空闲的时候,JavaScript才会去执行队列里的事件。
看下面的代码:
<!DOCTYPE HTML> <html> <head> <script type="text/javascript"> window.onload = function () { var a = 0; function one() { for (var i = 0; i < 10; i++) { console.log(i); setTimeout(function(){ console.log(a); a += i; },0); }; } function two() { alert(a); } one(); setTimeout(two,0); } </script> </head> </html>
这里其实one函数看着像是会正常把a从0加到9,然后alert出来。
但实际上的alert结果是100,为什么?
one函数的for循环是不会因为setTimeout停下的,它遇到setTimeout的时候只会把里面的回调函数放到队列里面去,然后继续i++。等执行完所有的for循环才会去执行刚才放到队列的函数。因为循环完了所以i是10,总共有10个相同的a+=i;操作的函数被调用,最后a的结果就变成了100了。
但是其实上面代码有部分我还是不明白,就是如果setTimeout(two,0);改成setTimeout(two(),0);的话,alert的结果就变成了0。
setTimeout的第一个参数是函数对象,如果变成two(),那回调函数就变成了two的返回值,因为需要用到two的返回值,two函数就会直接执行,在执行的时候a没有发生任何变化,所以输出就是0了。
附上setTimeout不带参数的一些写法:
setTimeout("alert('3秒后执行我')",3000); // 直接把执行语句放在双引号里当参数 setTimeout(function(){alert("3秒后执行我");},3000); // 直接把一个包含执行语句的匿名函数当参数 setTimeout(two,3000); // 把指针当参数 setTimeout("two()",3000); // 把two()函数放在双引号里当参数,相当于用eval()函数来解析他 setTimeout(function(){two();},3000); // 把要执行的函数放在一个匿名函数里当参数
带参数的写法:
setTimeout("two('"+arg1+"',"+"'"+arg2+"',"+....+"')",3000); // 尽量不要用这一样,很容易弄错 setTimeout(two,3000,arg1,arg2....); // 第一个参数是指针,第二个是延迟执行的时间,后面紧跟着的是调用函数所执行的参数 setTimeout(function(){two(arg1,arg2...);},3000); // 直接把要执行的函数已经参数放在匿名函数里当setTimeout的第一个参数