一道经典面试题-----setTimeout(function(){},0)

转载: http://www.w3cfuns.com/notes/17398/e8a1ce8f863e8b5abb530069b388a158/page/3.html#tagsbar

先看题:

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

结果是:0 1 2 3 3 3
很多公司面试都爱出这道题,此题考察的知识点还是蛮多的。
都考察了那些知识点呢?
异步、作用域、闭包。
我们来简化此题:

 setTimeout(function() {
console.log(1);
}, 0);
console.log(2); //先打印2,再打印1

因为是setTimeout是异步的。
正确的理解setTimeout的方式(注册事件):
有两个参数,第一个参数是函数,第二参数是时间值。
调用setTimeout时,把函数参数,放到事件队列中。等主程序运行完,再调用。

就像我们给按钮绑定事件一样:

 btn.onclick = function() {
alert(1);
};

这么写完,会弹出1吗。不会!!只是绑定事件而已! 必须等我们去触发事件,比如去点击这个按钮,才会弹出1。

setTimeout也是这样的!只是绑定事件,等主程序运行完毕后,再去调用。

setTimeout的时间值是怎么回事呢?

 setTimeout(fn, 2000)

程序会不会报错? 不会!而且还会准确得打印1。为什么? 因为真正去执行console.log(i)这句代码时,var i = 1已经执行完毕了!

所以我们进行dom操作。可以先绑定事件,然后再去写其他逻辑。

 window.onload = function() {
fn();
}
var fn = function() {
alert('hello')
};

这么写,完全是可以的。因为异步!

es5中是没有块级作用域的。

 for (var i = 0; i < 3; i++) {}
console.log(i); //3,也就说i可以在for循环体外访问到。所以是没有块级作用域。

这回我们再来看看原题。
原题使用了for循环。循环的本质是干嘛的?
是为了方便我们程序员,少写重复代码。

原题等价于:

 var i = 0;
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
i++;
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
i++;
setTimeout(function() {
console.log(i);
}, 0);
console.log(i);
i++;

因为setTimeout是注册事件。根据前面的讨论,可以都放在后面。
原题又等价于如下的写法:

 var i = 0;
console.log(i);
i++;
console.log(i);
i++;
console.log(i);
i++;
setTimeout(function() {
console.log(i);
}, 0);
setTimeout(function() {
console.log(i);
}, 0);
setTimeout(function() {
console.log(i);
}, 0); //弹出 0 1 2 3 3 3

怎么保证能弹出0,1, 2呢?

 for (var i = 0; i < 3; i++) {
setTimeout((function(i) {
return function() {
console.log(i);
};
})(i), 0); //改为立即执行的函数
console.log(i);
}

一道经典面试题-----setTimeout(function(){},0)的更多相关文章

  1. setTimeout(function(){}, 0);

    for (var i = 0; i < 3; i++) { setTimeout(function() { console.log(i); }, 0); console.log(i); } 结果 ...

  2. 关于fork的一道经典面试题

    这是一道面试题,问程序最终输出几个“-”: #include<stdio.h> #include<sys/types.h> #include<unistd.h> i ...

  3. 关于global和$GLOBALS[]的一道经典面试题

    在不执行程序的情况下,你觉得的输出结果是什么? <?php $var1 = 1; $var2 = 2; function test(){ global $var1,$var2; $var2 = ...

  4. 一道经典面试题,atoi函数的实现

    参考资料 (1)atoi函数的实现 (2)<剑指offer> 题目分析 本题需要注意的有几个方面: (1)检查输入参数,指针是否为NULL: (2)去除字符串前面的空格 (3)处理正负符号 ...

  5. java120经典面试题

    经典面试题 -----version 1.0 题注:以下答案仅限本人个人见解,若有错误和建议请多多指教.QQ:1807812486 题目来源 1.什么是Java虚拟机?为什么Java被称作是" ...

  6. for(var i=1;i<=3;i++){ setTimeout(function(){ console.log(i); },0); };答案:4 4 4。

    看面试题时,发现了一道较为经典的面试题,代码如下 for(var i=1;i<=3;i++){ setTimeout(function(){ console.log(i); },0); }; / ...

  7. 解析js中作用域、闭包——从一道经典的面试题开始

    如何理解js中的作用域,闭包,私有变量,this对象概念呢? 就从一道经典的面试题开始吧! 题目:创建10个<a>标签,点击时候弹出相应的序号 先思考一下,再打开看看 //先思考一下你会怎 ...

  8. 一道经典JS面试题

    超过80%的候选人对下面这道JS面试题的回答情况连及格都达不到.这究竟是怎样神奇的一道JS面试题?他考察了候选人的哪些能力?对正在读本文的你有什么启示? 不起眼的开始 招聘前端工程师,尤其是中高级前端 ...

  9. OpenJDK源码研究笔记(五)-缓存Integer等类型的频繁使用的数据和对象,大幅度提升性能(一道经典的Java笔试题)

    摘要 本文先给出一个看似很简单实则有深意的Java笔试面试题,引出JDK内部的缓存. JDK内部的缓存,主要是为了提高Java程序的性能. 你能答对这道"看似简单,实则有深意"的J ...

随机推荐

  1. 自制基于HMM的python中文分词器

    不像英文那样单词之间有空格作为天然的分界线, 中文词语之间没有明显界限.必须采用一些方法将中文语句划分为单词序列才能进一步处理, 这一划分步骤即是所谓的中文分词. 主流中文分词方法包括基于规则的分词, ...

  2. 异步上传文件,jquery+ajax,显示进度条

    根据网上的资料,做了很多修改,结果发现使用ajax上传数据时若要监听xhr.upload.addEventListener("progress",functiion(e),fals ...

  3. Docker配置阿里云加速地址

    首先需要注册一个阿里云账号,只要注册账号就可以,不用充钱购买任何阿里云服务! 打开阿里云网站https://cr.console.aliyun.com,登陆自己的阿里云账号. 然后只需要在服务器配置d ...

  4. Spring基础(8) : 延迟加载,Bean的作用域,Bean生命周期

    1.延迟加载 <bean id="p" class="com.Person" lazy-init="true"/> @Confi ...

  5. golang中的 time 常用操作

    时间戳 时间戳 (例如: 1554714009) time.now().Unix() 格式时间 (例如: 2019-04-08 17:00:09) time.Now().Format("20 ...

  6. sqlserver清除缓存(转载)

    sqlserver清除缓存,记录查询时间   1 2 3 4 5 6 7 8 9 10 11 12 --1. 将当前数据库的全部脏页写入磁盘.“脏页”是已输入缓存区高速缓存且已修改但尚未写入磁盘的数据 ...

  7. windows 搭建 angular2 开发环境--白纸新手可以参考一下

    初次接触angular,感觉接触一项新的东西真的是很艰难,自从听我朋友说起angular,就对这个东西产生了一些兴趣,就开始研究,经过艰辛的各种查资料各种头痛,终于是把这环境给搭上了·最起码是可以运行 ...

  8. 233 Matrix(hdu5015 矩阵)

    233 Matrix Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  9. 桥接模式(Bridge)

    1.概念 桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化,属于结构性模式的一种. 2.模式结构 Abstraction(抽象类):定义抽象接口,拥有一个Implementor类型的对象引 ...

  10. jquery 简单归纳 -- 前端知识

    jquery 什么是jQuery? jquery是轻量级的JavaScript库,核心是javascript,兼容css和各种浏览器,核心理念是写得少做得多(write less do more). ...