先看下面一个比较坑的代码

for (var i=1; i<=5; i++) {
setTimeout( function timer() {
console.log(i);
}, i*1000 );
}

首先一个for循环, 会执行五次, setTimeout被执行了五次

但里面的timer这时候并没有执行, 而是依次在1 2 3 4 5秒后执行

此时只建立了全局上下文;

timer放在了事件队列里面执行; timer执行时, for循环已经完成

全局作用域中的i变量值变成了6, 此时创建timer的作用域和作用域链

因为timer里面并没有定义i, 也没有给i赋值, 所以timer 在自己的作用域是找不到i的,

只能沿着作用域往上找, 找到全局作用域的i,

timeri 获取全局作用域i, 也就是6, 所以5次timer都是输出6

当加入闭包的时候, 情况就不一样了。

for (var i=1; i<=5; i++) {

            (function(j) {
window.setTimeout(function(){console.log(j)}, j*1000);
})(i)
}

第一次 for循环的时候, 同时又有自执行函数

也就是在for执行的同时, 执行了匿名函数, 创建了匿名函数的作用域, 此时建立了匿名函数的上下文环境;

进入匿名函数的作用域的时候, 包含了一个内部函数 function(){console.log(j)}

同时这个函数被全局变量 window.setTimeout引用,这就形成了闭包!

在匿名函数执行完后,匿名函数的执行上下文出栈

也就是在for循环第一次执行完后,

匿名函数的的活动变量 j , 由于闭包的关系,并没有被销毁,

而是保存在第一个window.setTimeout定时器中, 此时i 是1; j也是1; 这个值会一直保存在第一个定时器属性中;

直到第一个定时器被销毁;

然后进入第二次循环, 同理 又进入匿名函数, 创建了第二个闭包, 闭包的活动变量j 被第二个定时器引用;

也会保存在在第二个定时器中, 此时 i,j都是2;

依次类推, 3 4 5; 完成需求!

setTimeout 与 闭包。。。的更多相关文章

  1. setTimeout 学习闭包

    @(技术笔记)[css] 学习参考网站 css 网站,可供参考 javascript学习网站 var create = function (i){ return function(){ console ...

  2. setTimeout使用闭包功能,实现定时打印数值

    我们这次使用setTimeout来实现一个按照时间定时,依次打印数值的例子.其实在早期的时候,也是我经常犯的一个错误,或者实现这种能力,似乎js比较牵强,其实是我的错,哈哈!没能理解JS强大之处.我们 ...

  3. 当setTimeout遇到闭包

    1: function myTest(){ for(var i=0; i< 5; i++){ setTimeout(console.log(i), 0); } } myTest(); 或者比较正 ...

  4. setTimeOut和闭包

    掘金上看到一个setTimeout与循环闭包的思考题.拿过来看了下,一方面了解settimeout的运行机制,还有就是js闭包的特性.关于闭包,有如下解释: 在这里写一点我对闭包的理解.理解闭包的关键 ...

  5. 由一道面试题简单扩展 — setTimeout、闭包

    在一个前端公众号,看到这么一个号称简单的面试题: 1.以下程序输出什么? <script type="text/javascript"> function init() ...

  6. 附件1:setTimeout与闭包

    我在详细图解作用域链与闭包一文中的结尾留下了一个关于setTimeout与循环闭包的思考题. 利用闭包,修改下面的代码,让循环输出的结果依次为1, 2, 3, 4, 5 for (var i=1; i ...

  7. js闭包(三)

    场景一:采用函数引用方式的setTimeout调用 闭包的一个通常的用法是为一个在某一函数执行前先执行的函数提供参数.例如,在web环境中,一个函数作为setTimeout函数调用的第一个参数,是一种 ...

  8. Web前端-JavaScript基础教程上

    Web前端-JavaScript基础教程 将放入菜单栏中,便于阅读! JavaScript是web前端开发的编程语言,大多数网站都使用到了JavaScript,所以我们要进行学习,JavaScript ...

  9. 菜鸟凉经(华为、firehome、大华)

    面试通知都是前一天来的,准备的时间很少,所以表现也不是特别满意,来看面经吧: 华为一面(IT应用工程师): 1.自我介绍:(华为面试都是1对1,面前的是个温柔的小哥,挺放松的) 2.你主要会的it技术 ...

随机推荐

  1. ireport表单制作

    关于ireport的表单制作,可参考http://blog.csdn.net/wlwlwlwl015/article/details/51312853 这里主要讲解下如何在表单中加入table,如何让 ...

  2. 使用INTERSECT运算符

    显示符合以下条件的雇员的雇员ID 和职务ID:这些雇员的当前职务与以前的职务相同,也就是说这些雇员曾担任过别的职务,但现在又重新担任了以前的同一职务. hr@TEST0924> SELECT e ...

  3. GitHub学习四-查看版本库信息

    首先,只有在本地init以及关联到远程版本库的本地版本库,才能查看版本库信息 1.查看版本库名字 如果忘了名字,直接运行git remote 2.git remote show <name> ...

  4. Mybatis 查询tinyint(1)的数据库字段时会自动转换成boolean类型

    解决方案:将字段的tinyint(1)变成tinyint(2)

  5. [LeetCode] 295. Find Median from Data Stream ☆☆☆☆☆(数据流中获取中位数)

    295. Find Median from Data Stream&数据流中的中位数 295. Find Median from Data Stream https://leetcode.co ...

  6. weblogic安装教程(以weblogic 11g为例)

    1.下载jdk和weblogic安装介质 一般的搭配是jdk1.5+weblogic92.jdk1.6+weblogic11g(weblogic10.3.6) jdk历史版本下载链接:http://w ...

  7. Struts 2 初步入门(五)之接受参数

    1.使用action的属性接受参数 执行顺序为:前端提交参数--->LoginAction.do进行处理--->处理成功后,跳转到sucess.jsp文件. (1)新建login.jsp文 ...

  8. Jquery如何禁止鼠标右键菜单

    jquery中使用contextmenu事件,如果返回true,则允许右键菜单:如果返回false,则禁止右键菜单 导入文件 <script type="text/javascript ...

  9. VMware workstation 14 Pro下载、安装及激活码

    虚拟机安装 1.百度搜索VMware应用程序 2.功能介绍 3.下载完成 4.开始安装 双击应用程序开始安装 5.点击“下一步” 6.勾选“我接受” 选择“下一步” 7.安装文件的选择:1.默认安装路 ...

  10. 003-RHEL7-Linux系统维护管理命令使用

    系统维护管理命令: date  查看日期,设置日期 只有超级用户才能用date命令设置时间 date  --help  显示时间的帮助命令 date{选项} 显示时间格式(以+开头,后面接时间格式) ...