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,定时器,闭包等)的更多相关文章

  1. maven webapp栽坑录

    一.需求 如何将一个java web项目传给别人?放到github上.要想放到github上,就要学会git,markdown和maven.像那些jar包是不鼓励传到github上的,应该尽量把源文件 ...

  2. 【React踩坑记二】react项目实现JS路由跳转

    这里使用的是4.31版本的react-router-dom "react-router-dom": "^4.3.1", 直接使用以下代码即可实现路由跳转 thi ...

  3. java抽象-老师的生日-逻辑思维-有趣的面试题-遁地龙卷风

    (-1)写在前面 都快去北京了,硬生生的安排一场java考试,对于那些特别细节的东西我忘了吧也不觉得有什么不好,以前都记得,也都见过,只不过平时不常用连接断了,但是你死记硬背是没用的,一段时间后还是会 ...

  4. 一道阿里面试题(js)

    写一个求和的函数sum,达到下面的效果 // Should equal 15 sum(1, 2, 3, 4, 5); //Should equal 0 sum(5, 'abc', -5); //Sho ...

  5. 分享一道JS前端闭包面试题

    输出以下代码的结果 function fun(n,o){ console.log(o); return { fun:function(m){ return fun(m,n);//[1] } } } v ...

  6. 一道面试题关于js中添加动态属性

    js中数据类型包含基本数据类型和引用类型,基本类型包括:string.null.undefined.number.boolean.引用类型即是对象比如:array  .function以及自定义对象等 ...

  7. 一道面试题关于js中逗号

    一.今天遇到一个面试题,自我感觉是会,但是却做错了.人都是这样,自我感觉良好,其实也就预警自己已经忽视一些细节以及一些自我感知. 面试题: ,j=,k; ,j<;i++,j++){ k=i+j; ...

  8. 踩坑,vue项目中,main.js引入scss文件时报错

    当我们在src目录下创建.scss文件,并在main.js中引用,运行时会报: ERROR Failed to compile with 1 errors 5:25:07 PMThis relativ ...

  9. 一道面试题:js返回函数, 函数名后带多个括号的用法及join()的注意事项

    博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/13/js%E8%BF%94%E5%9B%9E%E5%87%BD%E6%95%B0%E ...

随机推荐

  1. HashMap,LinkedHashMap,TreeMap之间的区别

    java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap . Map 主要用于存储键( ...

  2. scrapy爬取验证码登录网页

    scrapy 验证码登录程序, https://accounts.douban.com/login # -*- coding: utf-8 -*- import scrapy import urlli ...

  3. Git之安装管理

    1.Git安装部署 Git是分布式的版本控制系统,我们只要有了一个原始Git版本仓库,就可以让其他主机克隆走这个原始版本仓库,从而使得一个Git版本仓库可以被同时分布到不同的主机之上,并且每台主机的版 ...

  4. python模块--os模块的用法

    os.getcwd() 获取当前工作的目录,即当前python脚本工作的目录路径 os.phdir("dirname") 改变当前脚本的工作目录:相当于shell下cd os.cu ...

  5. Virsh中创建虚拟机两种方式define和create的区别

    本质上两者一样的,都是从xml配置文件创建虚拟机 define  丛xml配置文件创建主机但是不启动 create  同样是丛xml配置文件创建主机,但是可以指定很多选项,比如是否启动,是否连接控制台 ...

  6. Wordpress网站添加七牛云cdn

    1.一个搭建好的网站和七牛云账号 2.七牛云进入控制面板 3创建存储空间 4创建好了空间拿七牛给你了测试域名(但只可以使用30天)所以绑定自定义域名(这个必须是备案过的) 5.设置自定义域名(加速域名 ...

  7. DeepLearning4J 环境搭建【转】

    深度学习Deeplearning4j eclipse 开发环境搭建 eclipse设置deeplearning4j开发环境:手动添加jar包 https://deeplearning4j.org/cn ...

  8. curl post数据

    调用方式: $header = self::getHeader(); $data = self::postUrl($url, $header); /** * 组合Header * @return ty ...

  9. C++使用回溯法实现N皇后问题的求解

    回溯法是个很无聊的死算方法,没什么技巧,写这篇博客主要原因是以前思路不太清晰,现在突然想用回溯法解决一个问题时,无法快速把思路转换成代码. ------------------------------ ...

  10. 使用Apache POI操作Excel文件---在已有的Excel文件中插入一行新的数据

    package org.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundEx ...