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

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. 小程序for循环嵌套

    <view class='nocontnt' wx:if="{{listLength == 0 }}"> 暂无相关评论 </view> <view c ...

  2. 使用scp上传和下载文件

    利用scp传输文件 1.从服务器下载文件 scp username@servername:/path/filename /tmp/local_destination 例如scp codinglog@1 ...

  3. SQLServer2012数据库降级至SQLServer2008R2的方法

      一.  背景 因为对方的客户的服务器安装的数据版本2012,公司开发同事需要客户数据库的备份数据,但是公司数据版本是2008R2的,无法还原. 由于2012备份无法直接还原至2008R2(MSSQ ...

  4. SpringBoot项目Shiro的实现(二)

    在看此小节前,您可能需要先看:http://www.cnblogs.com/conswin/p/7478557.html 紧接上一篇,在上一篇我们简单实现了一个Springboot的小程序,但我们发现 ...

  5. Leetcode 124 *

    /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...

  6. Beta阶段——第5篇 Scrum 冲刺博客

    Beta阶段--第5篇 Scrum 冲刺博客 标签:软件工程 一.站立式会议照片 二.每个人的工作 (有work item 的ID) 昨日已完成的工作 人员 工作 林羽晴 完成了邮箱发送功能的测试,测 ...

  7. html 巧用data-for藏自定义属性

    <div class="form-ele"> <label for="week" class="label col-1"& ...

  8. PyQt+Html+Js

    先做记录,后面有时间在仔细研究 https://www.cnblogs.com/jiangjh5/p/7209315.html?utm_source=itdadao&utm_medium=re ...

  9. python+ajaxFileUpload 无刷新上传文件

    需要准备文件 http://pan.baidu.com/s/1bp4N3nL   qqi0 html <script src="{% static 'js/jquery.js' %}& ...

  10. linux的命令:

    uname -r  linux的版本号 uname -a  显示系统名.节点名称.操作系统的发行版号.操作系统版本.运行系统的机器 ID 号 cd /dev/ 切换到根目录: ls 查看根目录文件