一次围绕setTimeout的前端面试经验分享


Posted in Javascript onJune 15, 2017

前言

前端这个近年的热门领域,搞事气氛特别强烈,我朋友小伟最近就在疯狂面试,遇到了许多有趣的面试官,有趣的面试题,我来帮这个搞事 boy 转述一下。

具体如下:

以下是我一个朋友的故事,真的不是我。

for (var i = 0; i < 5; i++) {
 console.log(i);
}

“小伟,你说说这几行代码会输出什么?”

当面试官在 Sublime 打出这几行代码时,我竟有点蒙蔽。蛤?这不是最简单的一个循环吗?是不是有陷阱啊,我思索一下,这好像和我看的那个闭包的题很像啊,这面试官是不是没写完啊?有毒啊。

“应该是直接输出 0 到 4 吧...”,我弱弱的说到。

“是啊,别紧张,这题没啥陷阱,我就是随便写一下。”

(Excuse me?面试官你是来搞笑的吗,吓死老子了!)

“那你在看看这几行代码会输出什么?”

for (var i = 0; i < 5; i++) {
 setTimeout(function() {
 console.log(i);
 }, 1000 * i);
}

额,什么鬼,怎么还不是我背了那么多遍的那道闭包题,让我想想。 setTimeout 会延迟执行,那么执行到 console.log 的时候,其实 i 已经变成 5 了,对,就是这样,这么简单怎么可能难到老子。

“应该是开始输出一个 5,然后每隔一秒再输出一个 5,一共 5 个 5。”

“对,那应该怎么改才能输出 0 到 4 呢?”

终于到我熟悉的了,加个闭包就解决了,稳!

for (var i = 0; i < 5; i++) {
 (function(i) {
 setTimeout(function() {
  console.log(i);
 }, i * 1000);
 })(i);
}

“很好,那你能说一下,我删掉这个 i 会发生什么吗?”

for (var i = 0; i < 5; i++) {
 (function() {
 setTimeout(function() {
  console.log(i);
 }, i * 1000);
 })(i);
}

“这样子的话,内部其实没有对 i 保持引用,其实会变成输出 5。”

“很好,那我给你改一下,你看看会输出什么?”

for (var i = 0; i < 5; i++) {
 setTimeout((function(i) {
 console.log(i);
 })(i), i * 1000);
}

蛤?什么鬼,这是什么情况,让我想想。这里给 setTimeout 传递了一个立即执行函数。额,setTimeout 可以接受函数或者字符串作为参数,那么这里立即执行函数是个啥呢,应该是个 undefined ,也就是说等价于:

setTimeout(undefined, ...);

而立即执行函数会立即执行,那么应该是立马输出的。

“应该是立马输出 0 到 4 吧。”

“哎哟,不错哦,最后一题,你对 Promise 了解吧?”

“还可以吧...”

“OK,那你试试这道题。”

setTimeout(function() {
 console.log(1)
}, 0);
new Promise(function executor(resolve) {
 console.log(2);
 for( var i=0 ; i<10000 ; i++ ) {
 i == 9999 && resolve();
 }
 console.log(3);
}).then(function() {
 console.log(4);
});
console.log(5);

WTF!!!!我想静静!

这道题应该考察我 JavaScript 的运行机制的,让我理一下思路。

首先先碰到一个 setTimeout,于是会先设置一个定时,在定时结束后将传递这个函数放到任务队列里面,因此开始肯定不会输出 1 。

然后是一个 Promise,里面的函数是直接执行的,因此应该直接输出 2 3 。

然后,Promise 的 then 应当会放到当前 tick 的最后,但是还是在当前 tick 中。

因此,应当先输出 5,然后再输出 4 。

最后在到下一个 tick,就是 1 。

“2 3 5 4 1”

“好滴,等待下一轮面试吧。”

So easy!妈妈再也不用担心我的面试了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jquery 定位input元素的几种方法小结
Jul 28 Javascript
js控制页面控件隐藏显示的两种方法介绍
Oct 09 Javascript
JS操作Cookie写入和读取实例代码
Oct 20 Javascript
JS控件ASP.NET的treeview控件全选或者取消(示例代码)
Dec 16 Javascript
DOM事件阶段以及事件捕获与事件冒泡先后执行顺序(图文详解)
Aug 18 Javascript
Jquery 1.9.1源码分析系列(十二)之筛选操作
Dec 02 Javascript
Vue2.0组件间数据传递示例
Mar 07 Javascript
Vue中img的src属性绑定与static文件夹实例
May 18 Javascript
vue的传参方式汇总和router使用技巧
May 22 Javascript
微信小程序框架的页面布局代码
Aug 17 Javascript
vue项目在webpack2实现移动端字体自适配功能
Jun 02 Javascript
vue:el-input输入时限制输入的类型操作
Aug 05 Javascript
利用JS对iframe父子(内外)页面进行操作的方法教程
Jun 15 #Javascript
使用Require.js封装原生js轮播图的实现代码
Jun 15 #Javascript
JavaScript实现选中文字提示新浪微博分享效果
Jun 15 #Javascript
详解vue跨组件通信的几种方法
Jun 15 #Javascript
Bootstrap响应式导航由768px变成992px的实现代码
Jun 15 #Javascript
javascript完美实现给定日期返回上月日期的方法
Jun 15 #Javascript
JS自动生成动态HTML验证码页面
Jun 14 #Javascript
You might like
PHP脚本的10个技巧(4)
2006/10/09 PHP
php自定义的格式化时间示例代码
2013/12/05 PHP
php+ajax实现无刷新数据分页的办法
2015/11/02 PHP
通过修改Laravel Auth使用salt和password进行认证用户详解
2017/08/17 PHP
Yii2.0实现生成二维码功能实例
2017/10/24 PHP
Laravel使用原生sql语句并调用的方法
2019/10/09 PHP
JavaScript实现自动对页面上敏感词进行屏蔽的方法
2015/07/27 Javascript
AngularJS使用ngOption实现下拉列表的实例代码
2016/01/23 Javascript
原生JS实现风箱式demo,并封装了一个运动框架(实例代码)
2016/07/22 Javascript
js关于getImageData跨域问题的解决方法
2016/10/14 Javascript
JavaScript页面实时显示当前时间实例代码
2016/10/23 Javascript
javascript 中的try catch应用总结
2017/04/01 Javascript
6行代码实现微信小程序页面返回顶部效果
2018/12/28 Javascript
小程序多图列表实现性能优化的方法步骤
2019/05/28 Javascript
原生JavaScript写出Tabs标签页的实例代码
2020/07/20 Javascript
[04:29]DOTA2亚洲邀请赛小组赛第一日 TOP10精彩集锦
2015/02/01 DOTA
[02:55]含熏伴清风,风行者至宝、屠夫身心及典藏宝瓶二展示
2020/09/08 DOTA
Python多进程编程技术实例分析
2014/09/16 Python
Python进阶_关于命名空间与作用域(详解)
2017/05/29 Python
pygame游戏之旅 添加游戏暂停功能
2018/11/21 Python
python实现弹窗祝福效果
2019/04/07 Python
Python爬虫 批量爬取下载抖音视频代码实例
2019/08/16 Python
使用OpenCV实现仿射变换—平移功能
2019/08/29 Python
Python ini文件常用操作方法解析
2020/04/26 Python
Python下载网易云歌单歌曲的示例代码
2020/08/12 Python
总结Pyinstaller的坑及终极解决方法(小结)
2020/09/21 Python
Python3+Flask安装使用教程详解
2021/02/16 Python
德国的大型美妆个护电商:Flaconi
2020/06/26 全球购物
css animation配合SVG制作能量流动效果
2021/03/24 HTML / CSS
就业协议书范本
2014/04/11 职场文书
2014年政教处工作总结
2014/12/20 职场文书
公务员考察材料
2014/12/23 职场文书
MySQL通过binlog恢复数据
2021/05/27 MySQL
分析并发编程之LongAdder原理
2021/06/29 Java/Android
Golang 并发下的问题定位及解决方案
2022/03/16 Golang
SpringBoot中获取profile的方法详解
2022/04/08 Java/Android