setTimeout 和 setInterval 潜在错误
setTimeout 的第一个参数是函数对象,一个常犯的错误是这样的
setTimeout(foo(), 1000), 这里回调函数是 foo 的返回值,而不是 foo 本身。 大部分情况下,这是一个潜在的错误,因为如果函数返回 undefined, setTimeout 也不会报错。
正确方式:
1 2 3 4 5 6 7 8 9 | function Foo() { this.value = 42; this.method = function() { // this 指向全局对象 console.log(this.value); // 输出:undefined }; setTimeout(this.method, 500); } new Foo(); |
当回调函数的执行被阻塞时,setInterval 仍然会发布更多的回调指令。在很小的定时间隔情况下,这会导致回调函数被堆积起来。
最简单也是最容易控制的方案,是在回调函数内部使用 setTimeout 函数:
1 2 3 4 5 | function foo(){ // 阻塞执行 1 秒 setTimeout(foo, 1000); } foo(); |
setTimeout 和 setInterval 也接受第一个参数为字符串的情况。这个特性绝对不要使用,因为它在内部使用了 eval。eval 函数会从全局作用域中执行。当需要向回调函数传递参数时,可以创建一个匿名函数,在函数内执行真实的回调函数。
小心 eval:
1 2 3 4 5 6 7 8 9 10 | function foo() { // 将会被调用 } function bar() { function foo() { // 不会被调用 } setTimeout('foo()', 1000); } bar(); |