一道容易栽坑的有趣的面试题(关于js,定时器,闭包等)
1.首先下面代码输出什么?
for (var i = 0; i < 5; i++) {
console.log(i);
}
输出:0 1 2 3 4
2.上面只是普通的输出,没有陷阱再看下面这个题(套路开始了)
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
}
输出:5 5 5 5 5
setTimeout 会延迟执行,那么执行到 console.log 的时候,其实 i 已经变成 5 了,因此会输出5个5
3.上面的题超出我们的预想,我们肯定想得到的是0 1 2 3 4,那么问题来了 怎么才能输出0 1 2 3 4呢
for (var i = 0; i < 5; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i);
}
或者:
for(var i = 0; i < 5; i++) {
setTimeout(function(i) {
return function() {
console.log(i);
};
}(i), i * 1000);
}
输出:0 1 2 3 4
加上闭包,就能解决这个问题
4.如第一个假设删除了function(i)中的i呢,怎么办?
for (var i = 0; i < 5; i++) {
(function() {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i);
}
输出:5 5 5 5 5
内部其实没有对 i 保持引用,其实会变成输出 5个5
5.再更改一下
for (var i = 0; i < 5; i++) {
setTimeout((function(i) {
console.log(i);
})(i), i * 1000);
}
输出:0 1 2 3 4 (立刻输出,没有时间间隔)
给 setTimeout 传递了一个立即执行函数。setTimeout 可以接受函数或者字符串作为参数,那么这里立即执行函数是个啥呢,应该是个 undefined ,也就是说等价于:
setTimeout(undefined, ...);
而立即执行函数会立即执行,那么应该是立马输出的。
“应该是立马输出 0 到 4 吧。”
6.对于promise的考察
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);
输出:2 3 5 4 1
考察 JavaScript 的运行机制的,
首先先碰到一个 setTimeout,于是会先设置一个定时,在定时结束后将传递这个函数放到任务队列里面,因此开始肯定不会输出 1 。
然后是一个 Promise,里面的函数是直接执行的,因此应该直接输出 2 3 。
然后,Promise 的 then 应当会放到当前 tick 的最后,但是还是在当前 tick 中。
因此,应当先输出 5,然后再输出 4 。
最后在到下一个 tick,就是 1 。
所以输出:2 3 5 4 1
一道容易栽坑的有趣的面试题(关于js,定时器,闭包等)的更多相关文章
- maven webapp栽坑录
一.需求 如何将一个java web项目传给别人?放到github上.要想放到github上,就要学会git,markdown和maven.像那些jar包是不鼓励传到github上的,应该尽量把源文件 ...
- 【React踩坑记二】react项目实现JS路由跳转
这里使用的是4.31版本的react-router-dom "react-router-dom": "^4.3.1", 直接使用以下代码即可实现路由跳转 thi ...
- java抽象-老师的生日-逻辑思维-有趣的面试题-遁地龙卷风
(-1)写在前面 都快去北京了,硬生生的安排一场java考试,对于那些特别细节的东西我忘了吧也不觉得有什么不好,以前都记得,也都见过,只不过平时不常用连接断了,但是你死记硬背是没用的,一段时间后还是会 ...
- 一道阿里面试题(js)
写一个求和的函数sum,达到下面的效果 // Should equal 15 sum(1, 2, 3, 4, 5); //Should equal 0 sum(5, 'abc', -5); //Sho ...
- 分享一道JS前端闭包面试题
输出以下代码的结果 function fun(n,o){ console.log(o); return { fun:function(m){ return fun(m,n);//[1] } } } v ...
- 一道面试题关于js中添加动态属性
js中数据类型包含基本数据类型和引用类型,基本类型包括:string.null.undefined.number.boolean.引用类型即是对象比如:array .function以及自定义对象等 ...
- 一道面试题关于js中逗号
一.今天遇到一个面试题,自我感觉是会,但是却做错了.人都是这样,自我感觉良好,其实也就预警自己已经忽视一些细节以及一些自我感知. 面试题: ,j=,k; ,j<;i++,j++){ k=i+j; ...
- 踩坑,vue项目中,main.js引入scss文件时报错
当我们在src目录下创建.scss文件,并在main.js中引用,运行时会报: ERROR Failed to compile with 1 errors 5:25:07 PMThis relativ ...
- 一道面试题:js返回函数, 函数名后带多个括号的用法及join()的注意事项
博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/13/js%E8%BF%94%E5%9B%9E%E5%87%BD%E6%95%B0%E ...
随机推荐
- flask第十一篇——自定义url转换器
首先和大家说一下flask的组成,flask其实是werkzeug(路由和http处理)+SQLAlchemy(数据库)+Jinja2(模板)组成的,今天我们要看到的东西就是`werkzeug`里面的 ...
- jenkins api 使用
1. java <dependency> <groupId>com.offbytwo.jenkins</groupId> <artifactId>je ...
- bower.json 的版本范围
bower.json 的版本范围 有小伙伴问 ~2.2.0 什么意思. 而且在git 的tags 中没有了 2.2.0 版本,怎么样? 实际上 ~2.2.0 的意思是 >=2.2.0 <2 ...
- Error unmarshalling file:/opt/test/jboss/server/defalt/conf/bootstrap.xml
启动命令:#/usr/local/jboss/bin/run.sh -b 0.0.0.0 -c defalt 启动的defalt写错了,应该写default.
- (转)Android studio 使用心得(五)—代码混淆和破解apk
这篇文章等是跟大家分享一在Android studio 进行代码混淆配置.之前大家在eclipse上也弄过代码混淆配置,其实一样,大家可以把之前在eclipse上的配置文件直接拿过来用.不管是.cfg ...
- mqtt 异步消息 长连接 解析
mqtt 是轻量级基于代理的发布/订阅的消息传输协议,设计思想是开放,简单,轻量级,且易于实现,这些优点使得他受用于任何环境 该协议的特点有: 使用发布/订阅消息的模式,提供一对多的消息发布,解除应用 ...
- Brocade FC Switch 光信号强度查看
步骤: 1.先运行,porterrshow 查看口状态,然后'statsclear' and 'slotstatsclear' 2.查看:porterrshow,看下port 口的情况 3.收集sup ...
- Django在Eclipse下配置启动端口号
首先,在Eclipse左侧树形菜单中找到要更改端口号的项目: 然后,在这里右键选择属性,打开属性界面之后选择Run/Debug Setting,并在其中找到已有的启动项,如果没有可以新建或启动一次. ...
- windows7下怎样安装whl文件(python)
本文转载自:http://blog.csdn.net/fhl812432059/article/details/51745226 windows7 python2.7 1.用管理员方式打开cmd 2. ...
- (转)Inno Setup入门(十九)——Inno Setup类参考(5)
本文转载自:http://blog.csdn.net/yushanddddfenghailin/article/details/17251019 单选按钮 单选按钮在安装中也很常见,例如同一个程序可以 ...