之前去面试一家公司时,面试官出了一道关于js的setTimeout函数的题目:

 /*
*面试官给的原题目如下:
*执行mytest()后,控制台输出内容是_____
*function mytest() {
* for(var i = 0; i < 5; i ++)
* setTimeout(console.log(i),0);
*}
*但这应该不是面试官的问题,当时我也没有发现问题,回来测试后才发现,这个函数不是
*面试官要表达的意思。
*/
//正确的代码如下:
function mytest() {
for(var i = 0; i < 5; i ++)
setTimeout(function(){
console.log(i);
},0);
}

我的回答是:控制台输出为5 5 5 5 5,虽然答案对了,但是解释就太牵强了,我说是因为for语句之执行速度比setTimeout函数快,面试笑了笑,呜呜~~(这有毛关系)。
后来网上找了一些资料,参考了一些书籍,这里我给出一个靠谱的解释:

首先,我们必须承认,js是单线程的,即使是对于ajax异步方式或者像setTimeout这样的函数。

其次,我们要理解js函数的执行过程,对于setTimeout这样的函数来说并不是每次都能按照预定延迟的时间执行指定函数的。下面举一个列子:

比如有一个函数fun0在执行开始时创建了一个定时器T1,T1定时器将在200ms后被触发指定函数。这时我们需要考虑一个问题,假设fun0的执行时间为250ms(大于200ms),那将会怎样?前面已经说过,js是单线程的,所以不存在fun0和定时器同时执行的情况。这时候定时器制定的函数会在fun0执行完后才执行,定时器的等待时间为250ms,并不是我们指定的200ms。

对于javascript这样的执行方式,我们可以想象在函数执行过程中有两个队列。队列Q1是指执行队列,每次只能执行一个函数;队列Q2就是等待队列,存放着将要执行的函数。每当有一个函数要执行时,就会先把这个函数放进等待队列,如果Q1为空,那么久立即执行这个函数。当然在大多数情况下,函数都是立即执行的。

因此,我们可以知道,setTimeout定时器指定的函数必须要在当前执行队列为空时才会执行。

现在我们再来分析一下上面那道题,很显然,每次的for循环都触发了一个定时函数,这些定时函数有点特殊,是立即执行的(如果执行队列为空的话)。但是在每次触发时,for循环都还未结束,也就是执行队列不为空,此时新建的定是函数只能放在等待队列里无法立即执行。当最后一次for循环执行结束后,执行队列变为空,这时等待队列的函数就立即进入到了执行队列,于是就开始执行只控制台输出。因为setTimeout指定的匿名函数中i的值是一种引用值(自行谷歌脑补),所以输出结果为5 5 5 5 5。

如描述或理解有误,欢迎各位留言!!

对setTimeout函数的理解的更多相关文章

  1. JavaScript callback function 回调函数的理解

    来源于:http://mao.li/javascript/javascript-callback-function/ 看到segmentfault上的这个问题 JavaScript 回调函数怎么理解, ...

  2. js setTimeout函数

    最近在看JS DOM编程艺术,在第十章的动画里面有个setTimeout函数的例子中涉及了很多的引号,研究了好大一会才看明白,综合网上各个大神的解释和自己的理解,其原理是这样的: 首先看下程序源代码: ...

  3. opengl中对glOrtho()函数的理解

    glOrtho是创建一个正交平行的视景体. 一般用于物体不会因为离屏幕的远近而产生大小的变换的情况.比如,常用的工程中的制图等.需要比较精确的显示. 而作为它的对立情况, glFrustum则产生一个 ...

  4. 什么是setTimeout函数和setInterval函数?

    我们一般在浏览网页的时候,一般都会有图片轮播等,一些比较好玩的特效,接下来我就给大家讲讲这俩个函数! 一setTimeout函数和setInterval函数的语法以及应用 1.setTimeout函数 ...

  5. 回调函数透彻理解Java

    http://blog.csdn.net/allen_zhao_2012/article/details/8056665 回调函数透彻理解Java 标签: classjavastringinterfa ...

  6. 对c语言中malloc和free函数的理解

    最近在复习c语言的时候再次用到了malloc函数和free函数,此处着讲解一下自己对这两个函数的理解和认识. 一. malloc函数和free函数的基本概念和基本的用法 对于malloc函数: 1.  ...

  7. js中的回调函数的理解和使用方法

    js中的回调函数的理解和使用方法 一. 回调函数的作用 js代码会至上而下一条线执行下去,但是有时候我们需要等到一个操作结束之后再进行下一个操作,这时候就需要用到回调函数. 二. 回调函数的解释 因为 ...

  8. 浅谈setTimeout函数和setInterval函数

    前几天学了js,看到了两个非常有趣的函数,他们分别是setTimeout函数和setInterval函数,这两个函数能使网页呈现非常一些网页中比较常见的效果,比如说图片轮播,等一些非常好玩的效果.下面 ...

  9. JS匿名函数的理解

    js匿名函数的代码如下:(function(){ // 这里忽略jQuery 所有实现 })(); 半年前初次接触jQuery 的时候,我也像其他人一样很兴奋地想看看源码是什么样的.然而,在看到源码的 ...

随机推荐

  1. 如何将位置值写入simotion encoder?

    目标: 将变量值(任意实数)写入Encoder,作为encoder的实际位置值.例如,将MP177手轮的值写入编码器,达到SMC30配置手轮的功能. Platform: simotion D435-2 ...

  2. zendstudio 汉化

    http://archive.eclipse.org/technology/babel/index.php http://www.eclipse.org/babel/downloads.php 注册码 ...

  3. Docker和宿主机操作系统文件目录互相隔离的实现原理

    我们知道在Docker容器里是无法访问到宿主操作系统的文件目录的,但这种隔离是怎么实现的呢? 其实一点也不神奇--利用了Linux系统的内部命令chroot. chroot能将进程的根目录设置成任意指 ...

  4. Android 编辑框(EditText)属性学习

    EditText的属性很多,这里介绍几个:android:hint="请输入数字!"//设置显示在空间上的提示信息android:numeric="integer&quo ...

  5. 【转】你是不是也被Android Private Libraries、Referenced Libraries、android Dependency搞晕了~~

    一.v4.v7.v13的作用和用法 1.Android Support V4, V7, V13是什么? 本质上就是三个java library. 2.为什么要有support库?   是为了解决软件的 ...

  6. Hubtown(最大流)

    Hubtown 时间限制: 1 Sec  内存限制: 128 MB提交: 23  解决: 11[提交] [状态] [讨论版] [命题人:admin] 题目描述 Hubtown is a large N ...

  7. 2018.8.26 Spring自学如门

    什么是Spring? Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE De ...

  8. 2017.10.18 微机原理与接口----汇编语言语法和DOS功能调用

    4.1 汇编语言中的基本数据 ·标识符 ·常数 ·变量具有三个属性: (1)段地址(SEG):变量所在段的段地址 (2)偏移地址(OFFSET):变量所在段内的偏移地址 (3)类型(TYPE):每个变 ...

  9. 使用MongoDB 2.6 C++驱动中的连接池

    .post p{text-indent: 2em;} MongoDB2.6的CXX驱动(mongo-cxx-driver-26compat),内置包含了数据库连接池,方便管理数据库连接,但是官方文档说 ...

  10. 图解HTTP-1.web和网络基础

    目录 1. 3 项 WWW 构建技术 2. TCP/IP 是互联网相关的各类协议族的总称 协议(protocol) TCP/IP分层管理 TCP/IP通信传输流 封装(encapsulate) 3. ...