欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  web前端

js中的setTimeout()函数

程序员文章站 2022-03-13 21:37:36
...
在js中,setTimeout()函数是全局变量,无论在哪里它都是全局变量而不是局部变量。所以下面这个例子的结果可能让你大吃一惊:
function A() {
    this.b = function() {
        console.log(1)
    }
}
var c = new A()
setTimeout(c.b, 10)

可能有些人认为上面这个例子输出的结果是1,但是结果是undefined。这是因为setTImeout()函数是全局变量,它把里面的c.b发到全局变量中,而全局变量中没有b这个属性,所以返回的undefined。

在js中,setTimeout()函数的运行机制是这样的,setInterval()函数也一样。将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,setTimeout指定的代码,必须等到本次执行的所有代码都执行完,才会执行。·

每一轮Event Loop时,都会将“任务队列”中需要执行的任务,一次执行完。setTimeout和setInterval都是把任务添加到“任务队列”的尾部。因此,它们实际上要等到当前脚本的所有同步任务执行完,然后再等到本次Event Loop的“任务队列”的所有任务执行完,才会开始执行。由于前面的任务到底需要多少时间执行完,是不确定的,所以没有办法保证,setTimeout和setInterval指定的任务,一定会按照预定时间执行。

所以如果前面有一个函数被阻塞了,则一直等待该函数执行完才能运行。因为js是单线程的,所以比较容易会发生阻塞的。

在setTimeout()函数中,最快的运行时间是4毫秒,即使将延迟参数写为0或者负数,它都不会立马的运行。在延迟参数为0或负数时,需要等待当前脚步的同步任务和event loop(即任务队列)执行完毕才开始执行,由于参数为0或者负数,只是比其他setTimeout()函数尽可能早的运行函数,而参数为0或者负数本身优先级相同。如:

setTimeout('console.log(1)',0)
console.log(2)

返回的结果是2 1

setTimeout('console.log(1)',0)
setTimeout('console.log(2)',-1)
setTimeout('console.log(3)',-1)
setTimeout('console.log(4)',0)

返回的结果是1 2 3 4

在setTimeout()函数中,还有一点是要值得注意的。那就是它的第一个参数必须是需要编译的代码或者是一个函数方法。所以像上面的例子中,console.log()被单引号括起来变成一个字符串,在setTimeout中有一个eval()函数可以将字符串进行编译。如果我们将console.log()方法没有用单引号括起来,那么整个setTimeout()函数就会立即执行,而不会考虑有没有延迟参数。如我在美的的美云智数面试遇见过的这一道题一样:

console.log(1)

setTimeout(console.log(2),0)
  
console.log(3)
  
setTimeout(console.log(4),-1)

返回的结果是1 2 3 4,如果将单引号括起来,返回的结果是1 3 2 4

在js中想要清除setTimeout定时器,需要clearTimeout()这个函数。具体用法如下所示:

var a = setTimeout('console.log(1)', 1)
clearTimeout(a)

最后贴出一道题看看毕业了没有,对比下面三段代码,看分别输出上面:

for (var i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
    }, 0);
    console.log(i);
}
for (var i = 0; i < 3; i++) {
    setTimeout((function() {
        console.log(i);
    })(i), 0);
    console.log(i);
}
for (var i = 0; i < 3; i++) {
    setTimeout((function(i) {
        return function() {
            console.log(i);
        };
    })(i), 0);
    console.log(i);  
}

这道题设计了一些js的作用域的问题,我会专门写一篇文章介绍es5中作用域和es6中的作用域发生了哪些变化。

以上就是js中的setTimeout()函数的详细内容,更多请关注其它相关文章!