web前端一次性定时器怎么写(前端面试题 JavaScript 定时器)(1)

今天有事外出,所以就挑简单的来讨论 ——

定时器 setTimeout

定时器在面试题中经常出现,都是搭配来考察其他相关知识的。

定时器

下列代码会在控制台输出什么?

web前端一次性定时器怎么写(前端面试题 JavaScript 定时器)(2)

点击下面小程序可以浏览完整题目和选项。

上面是一道经典的题目,主要用于考察 JavaScript 的作用域事件队列

当执行 for 循环时候,调用 setTimeout 异步函数,将其中的回调函数推到事件队列中等待执行。

此时回调函数的执行时间,被设定为从 0s 到 4s。

又因为通过 var 声明的 i 变量并不是在 for 循环中,而是在声明的方法体内,在例子中是则是在全局作用域。

所以在 for 循环执行结束后,全局作用域的 i = 5

而到队列任务执行时,所有队列任务中执行的 console.log(i) 中都是访问全局函数中的 i。

所以结果就是:每隔 1 秒,控制台输出一个 5。

闭包

而想按顺序输出 1 到 5,以前会使用闭包

web前端一次性定时器怎么写(前端面试题 JavaScript 定时器)(3)

上面通过声明一个自执行的匿名函数,当循环时候,创建出 5 个闭包,每个闭包内的变量 i是循环时传进去的 i 值。

当队列任务被调用时,console.log(i) 为对应的闭包内的变量 i。

let

在 ES6 中,通过关键字 let,可以创建出块级作用域。产生和闭包一样的效果。

web前端一次性定时器怎么写(前端面试题 JavaScript 定时器)(4)

定时器参数

观察下列代码,控制台会怎样的输出呢?

web前端一次性定时器怎么写(前端面试题 JavaScript 定时器)(5)

控制台会立即输出 0 至 4。而不是间隔 1 秒输出 0 到 4。

因为 console.log(i) 已经是调用函数的形式,而不是一个函数句柄。所以在执行循环时候,就同时执行 console.log(i)。

那么,应该怎样修改呢?

web前端一次性定时器怎么写(前端面试题 JavaScript 定时器)(6)

setTimeout() 首个参数接收回调函数,第二个参数接收延时时间。

我们可能会忽略,setTimeout() 的后续参数都是作为附加参数,在定时器到期时候,传到回调函数中。

所以,只需要在附加参数中传进 i 即可。

结语

今天的内容较为简单,可能很多朋友都已经了解。这些都算是面试中的开胃菜,不得不会,千万别阴沟里翻船。

觉得不错的帮忙点个赞吧,欢迎评论区讨论。

,