专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

一道可以把你绕晕的Javascript面试题,来一起看看吧

ins518 2024-10-05 20:31:11 技术文章 11 ℃ 0 评论

前言

最近看到一道跟Javascript中的setTimeout和Promise有关的面试题,感觉很有趣。题目循序渐进,不断深入,虽然只是一道题目的简单变形,却考察了很多个知识点,今天我们就一起来看看这道题目吧。

Javascript

原始题目

我们就直接看题目的代码,首先是最简单的原始题目。

原始题目

上述的代码很简单,输出0,1,2,3,4。你可能会疑问,面试题会有这么简单?放心,好戏还在后头呢。

变形1

我们将上述的代码加上setTimeout,再进行输出,看看会输出什么?

变形1

上述代码每隔一秒会输出一个5。

这道题考察的是函数的闭包,如果不太清楚闭包知识的,可以去看看我写的这篇文章《前端面试中不可逃避的闭包问题,你真的了解吗?》。

变形2

那么如果我们想要每间隔一秒输出从0到4,该如何实现呢?

如果了解闭包知识的话,可以很容易想出通过立即执行函数解决。

变形2

通过上述的代码,就可以很容易达到我们的要求。

变形3

那么我们继续对题目做变形,我们去掉这个立即执行函数中的i参数,看看结果会输出什么?

变形3

通过在控制台中运行,我们发现结果和变形1一样,间隔一秒输出一个5,那么为什么会这样呢?

这是因为在立即函数内部并没有对i的引用,实际的i仍然为外部作用域中的i,所以结果会和变形1相同。

变形4

我们继续对这道题目做出变形,将setTimeout中函数改为一个立即执行函数,看看结果会是什么?

变形4

通过在控制台运行上述代码,得到的结果是立即输出0, 1, 2, 3, 4。为什么会这样呢?

根据setTimeout的用法,它接收的参数为函数或者函数的字符串表示,如果给setTimeout传递一个立即执行函数,则相当于传递了一个undefined,实际上是往定时器线程中添加了5个undefined。但是由于立即执行函数的存在,这个函数会立即执行,所以会立即输出0, 1, 2, ,3 ,4。

变形5

如果以上的部分你都能知道,那么我们再来个更难一点的变形,将setTimeout配合Promise一起使用,看看以下的一段代码会输出什么?

变形5

通过在控制台运行以上代码,我们得到结果是立即输出2, 3, 5, 4, 1,这是为什么呢?

首先在代码的开头,使用了setTimeout设置了一个定时器,虽然这个定时器的时间为0,但是根据Javascript中的事件队列机制,会将这个定时器添加到专属的定时器线程中,等到当前线程中的事件回调执行完后才能执行。不太懂Javascript的setTimeout机制的,可以去看看我写的这篇文章《Javascript中的setTimeout黑魔法》。

然后是定义一个Promise,这个Promise会在setTimeout之前执行。在Promise中执行了两个console.log(),所以会先输出2,3。

在Promise中有一个for循环,当循环执行到i等于9999时,执行resolve回调函数,这个resolve函数就是后面输出4的函数。但是由于Promise.then()的回调会在当前事件队列的最后执行,因此4会在5的后面输出。

在当前事件队列执行完后,才会执行setTimeout中的函数,因此1是最后输出的。

因此输出结果是2, 3, 5, 4, 1。

结束语

由一道最简单的题可以通过变形衍生出很多知识点的考题,看看你都会做吗?

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表