今天有事外出,所以就挑简单的来讨论 ——
定时器 setTimeout
定时器在面试题中经常出现,都是搭配来考察其他相关知识的。
定时器下列代码会在控制台输出什么?
点击下面小程序可以浏览完整题目和选项。
上面是一道经典的题目,主要用于考察 JavaScript 的作用域和事件队列。
当执行 for 循环时候,调用 setTimeout 异步函数,将其中的回调函数推到事件队列中等待执行。
此时回调函数的执行时间,被设定为从 0s 到 4s。
又因为通过 var 声明的 i 变量并不是在 for 循环中,而是在声明的方法体内,在例子中是则是在全局作用域。
所以在 for 循环执行结束后,全局作用域的 i = 5
而到队列任务执行时,所有队列任务中执行的 console.log(i) 中都是访问全局函数中的 i。
所以结果就是:每隔 1 秒,控制台输出一个 5。
闭包而想按顺序输出 1 到 5,以前会使用闭包。
上面通过声明一个自执行的匿名函数,当循环时候,创建出 5 个闭包,每个闭包内的变量 i是循环时传进去的 i 值。
当队列任务被调用时,console.log(i) 为对应的闭包内的变量 i。
let在 ES6 中,通过关键字 let,可以创建出块级作用域。产生和闭包一样的效果。
定时器参数
观察下列代码,控制台会怎样的输出呢?
控制台会立即输出 0 至 4。而不是间隔 1 秒输出 0 到 4。
因为 console.log(i) 已经是调用函数的形式,而不是一个函数句柄。所以在执行循环时候,就同时执行 console.log(i)。
那么,应该怎样修改呢?
setTimeout() 首个参数接收回调函数,第二个参数接收延时时间。
我们可能会忽略,setTimeout() 的后续参数都是作为附加参数,在定时器到期时候,传到回调函数中。
所以,只需要在附加参数中传进 i 即可。
结语今天的内容较为简单,可能很多朋友都已经了解。这些都算是面试中的开胃菜,不得不会,千万别阴沟里翻船。
觉得不错的帮忙点个赞吧,欢迎评论区讨论。
,