一次围绕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学习之闭包分析
Dec 02 Javascript
一行代码告别document.getElementById
Jun 01 Javascript
js防止页面被iframe调用的方法
Oct 30 Javascript
js获取元素外链样式的方法
Jan 27 Javascript
jQuery延迟加载图片插件Lazy Load使用指南
Mar 25 Javascript
Webwork 实现文件上传下载代码详解
Feb 02 Javascript
Jquery uploadify 多余的Get请求(404错误)的解决方法
Jan 26 Javascript
$.browser.msie 为空或不是对象问题的多种解决方法
Mar 19 Javascript
解决在vue项目中,发版之后,背景图片报错,路径不对的问题
Mar 06 Javascript
vue实现图片预览组件封装与使用
Jul 13 Javascript
记一次用ts+vuecli4重构项目的实现
May 21 Javascript
利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化)
Feb 24 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-redis中文文档介绍
2013/02/07 PHP
php基于表单密码验证与HTTP验证用法实例
2015/01/06 PHP
PHP判断浏览器、判断语言代码分享
2015/03/05 PHP
php htmlentities()函数的定义和用法
2016/05/13 PHP
thinkPHP框架实现的无限回复评论功能示例
2018/06/09 PHP
thinkphp集成前端脚手架Vue-cli的教程图解
2018/08/30 PHP
JavaScript获得选中文本内容的方法
2008/12/02 Javascript
DOM 中的事件处理介绍
2012/01/18 Javascript
jquery阻止冒泡事件使用模拟事件
2013/09/06 Javascript
全面解析Bootstrap表单使用方法(表单按钮)
2015/11/24 Javascript
jQuery position() 函数详解以及jQuery中position函数的应用
2015/12/14 Javascript
深入分析Javascript事件代理
2016/01/30 Javascript
原生JS实现导航下拉菜单效果
2020/11/25 Javascript
详解angular用$sce服务来过滤HTML标签
2017/04/11 Javascript
ES5 ES6中Array对象去除重复项的方法总结
2017/04/27 Javascript
vue实现登陆登出的实现示例
2017/09/15 Javascript
微信小程序tabBar用法实例详解
2017/12/04 Javascript
webpack多页面开发实践
2017/12/18 Javascript
JavaScript 中定义函数用 var foo = function () {} 和 function foo()区别介绍
2018/03/01 Javascript
Vue.js实现可配置的登录表单代码详解
2018/03/29 Javascript
详解vue路由篇(动态路由、路由嵌套)
2019/01/27 Javascript
微信小程序和百度的语音识别接口详解
2019/05/06 Javascript
原生JS使用Canvas实现拖拽式绘图功能
2019/06/05 Javascript
Vue v-bind动态绑定class实例方法
2020/01/15 Javascript
[04:48]DOTA2上海特锦赛小组赛第三日 TOP10精彩集锦
2016/02/28 DOTA
python进阶教程之词典、字典、dict
2014/08/29 Python
python 实现数组list 添加、修改、删除的方法
2018/04/04 Python
python射线法判断检测点是否位于区域外接矩形内
2019/06/28 Python
Python实现从N个数中找到最大的K个数
2020/04/02 Python
华为消费者德国官方网站:HUAWEI德国
2020/11/03 全球购物
项目投资合作意向书
2014/07/29 职场文书
公司自我介绍演讲稿
2014/08/21 职场文书
员工离职感谢信
2015/01/22 职场文书
小学教师见习总结
2015/06/23 职场文书
Python 中random 库的详细使用
2021/06/03 Python
Golang 实现WebSockets
2022/04/24 Golang