一次围绕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 相关文章推荐
JavaScript 变量基础知识
Nov 07 Javascript
为调试JavaScript添加输出窗口的代码
Feb 07 Javascript
弹出层之1:JQuery.Boxy (一) 使用介绍
Oct 06 Javascript
基于jquery的不规则矩形的排列实现代码
Apr 16 Javascript
javascript实现仿IE顶部的可关闭警告条
May 05 Javascript
javascript中的深复制详解及实例分析
Dec 29 Javascript
jQuery实现的分页功能示例
Jan 22 Javascript
微信小程序 循环及嵌套循环的使用总结
Sep 26 Javascript
前端js中的事件循环eventloop机制详解
May 15 Javascript
JS获取当前时间戳方法解析
Aug 29 Javascript
uniapp实现可滑动选项卡
Oct 21 Javascript
vue backtop组件的实现完整代码
Apr 07 Vue.js
利用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
把77A收信机改造成收音机
2021/03/02 无线电
php生成WAP页面
2006/10/09 PHP
mysql_connect localhost和127.0.0.1的区别(网络层阐述)
2015/03/26 PHP
Yii框架实现记录日志到自定义文件的方法
2017/05/23 PHP
JS提交并解析后台返回的XML的代码
2008/11/03 Javascript
9个javascript语法高亮插件 推荐
2009/07/18 Javascript
基于jquery &amp; json的省市区联动代码
2012/06/26 Javascript
jQuery 网易相册鼠标移动显示隐藏效果实现代码
2013/03/31 Javascript
javascript数组操作(创建、元素删除、数组的拷贝)
2014/04/07 Javascript
javascript中兼容主流浏览器的动态生成iframe方法
2014/05/05 Javascript
jQuery实现table隔行换色和鼠标经过变色的两种方法
2014/06/15 Javascript
Jquery+Ajax+PHP+MySQL实现分类列表管理(下)
2015/10/28 Javascript
JavaScript实现复制文章自动添加版权
2016/08/02 Javascript
JavaScript基于replace+正则实现ES6的字符串模版功能
2017/04/25 Javascript
jQuery获取所有父级元素及同级元素及子元素的方法(推荐)
2018/01/21 jQuery
vue.js移动数组位置,同时更新视图的方法
2018/03/08 Javascript
QQ跳转支付宝并自动领红包脚本(最新)
2018/06/22 Javascript
基于js判断浏览器是否支持webGL
2020/04/18 Javascript
Python获取电脑硬件信息及状态的实现方法
2014/08/29 Python
python查询mysql中文乱码问题
2014/11/09 Python
Python判断文本中消息重复次数的方法
2016/04/27 Python
Python2.7基于淘宝接口获取IP地址所在地理位置的方法【测试可用】
2017/06/07 Python
python基于FTP实现文件传输相关功能代码实例
2019/09/28 Python
基于keras输出中间层结果的2种实现方式
2020/01/24 Python
python实现遍历文件夹图片并重命名
2020/03/23 Python
Python单元测试及unittest框架用法实例解析
2020/07/09 Python
PyCharm 解决找不到新打开项目的窗口问题
2021/01/15 Python
细说CSS3中box属性中的overflow-x属性和overflow-y属性值的效果
2014/07/21 HTML / CSS
Shoes For Crews法国官网:美国领先的防滑鞋设计和制造商
2018/01/01 全球购物
医科大学生毕业的自我评价分享
2013/11/12 职场文书
公司企业表扬信
2014/01/11 职场文书
八一建军节部队活动方案
2014/02/04 职场文书
医院工作检讨书范文
2014/02/10 职场文书
天猫活动策划方案
2014/08/21 职场文书
Jackson 反序列化时实现大小写不敏感设置
2021/06/29 Java/Android
golang使用map实现去除重复数组
2022/04/14 Golang