setTimeout 与 闭包。。。
先看下面一个比较坑的代码
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 与 闭包。。。的更多相关文章
- setTimeout 学习闭包
@(技术笔记)[css] 学习参考网站 css 网站,可供参考 javascript学习网站 var create = function (i){ return function(){ console ...
- setTimeout使用闭包功能,实现定时打印数值
我们这次使用setTimeout来实现一个按照时间定时,依次打印数值的例子.其实在早期的时候,也是我经常犯的一个错误,或者实现这种能力,似乎js比较牵强,其实是我的错,哈哈!没能理解JS强大之处.我们 ...
- 当setTimeout遇到闭包
1: function myTest(){ for(var i=0; i< 5; i++){ setTimeout(console.log(i), 0); } } myTest(); 或者比较正 ...
- setTimeOut和闭包
掘金上看到一个setTimeout与循环闭包的思考题.拿过来看了下,一方面了解settimeout的运行机制,还有就是js闭包的特性.关于闭包,有如下解释: 在这里写一点我对闭包的理解.理解闭包的关键 ...
- 由一道面试题简单扩展 — setTimeout、闭包
在一个前端公众号,看到这么一个号称简单的面试题: 1.以下程序输出什么? <script type="text/javascript"> function init() ...
- 附件1:setTimeout与闭包
我在详细图解作用域链与闭包一文中的结尾留下了一个关于setTimeout与循环闭包的思考题. 利用闭包,修改下面的代码,让循环输出的结果依次为1, 2, 3, 4, 5 for (var i=1; i ...
- js闭包(三)
场景一:采用函数引用方式的setTimeout调用 闭包的一个通常的用法是为一个在某一函数执行前先执行的函数提供参数.例如,在web环境中,一个函数作为setTimeout函数调用的第一个参数,是一种 ...
- Web前端-JavaScript基础教程上
Web前端-JavaScript基础教程 将放入菜单栏中,便于阅读! JavaScript是web前端开发的编程语言,大多数网站都使用到了JavaScript,所以我们要进行学习,JavaScript ...
- 菜鸟凉经(华为、firehome、大华)
面试通知都是前一天来的,准备的时间很少,所以表现也不是特别满意,来看面经吧: 华为一面(IT应用工程师): 1.自我介绍:(华为面试都是1对1,面前的是个温柔的小哥,挺放松的) 2.你主要会的it技术 ...
随机推荐
- Permutations CodeForces - 736D (矩阵逆)
对于删除每个对(x,y), 可以发现他对答案的贡献为代数余子式$A_{xy}$ 复习了一下线代后发现代数余子式可以通过伴随矩阵求出, 即$A_{xy}=A^*[y][x]$, 伴随矩阵$A^*=|A| ...
- Remove Duplicate Letters(Java 递归与非递归)
题目介绍: Given a string which contains only lowercase letters, remove duplicate letters so that every l ...
- MVC实战之排球计分(三)—— 模型类的设计与实现
此软件使用的数据库连接方式code first 由EF框架产生数据库. code first需要对模型类设计和实现.模型类是现实实体在计算机中的表示.它贯穿于整个架构, 负担着在各层次及模块间传递数据 ...
- Java 8 forEach
1. forEach and Map 1.1 通常这样遍历一个Map Map<String, Integer> items = new HashMap<>(); items.p ...
- C# 3.0 / C# 3.5 Lambda 表达式
概述 Lambda 表达式的本质就是匿名函数.(而匿名方法的本质是委托) “Lambda 表达式”是一个匿名函数,可以包含表达式和语句,并且可用于创建委托或表达式树类型. (Lambda 表达式的运算 ...
- Spring注解之@Transactional对于事务异常的处理
spring对于事务异常的处理 unchecked 运行期Exception spring默认会进行事务回滚 比如:RuntimeException checked 用 ...
- 跳转到页面的某个anchor
var loc = document.location.toString().split('#')[0]; document.location = loc + '#' + anchor;
- 2015-09-22 css2
6.块元素和行内元素 1. 块元素特点:默认显示在父标签的左上角 块级元素默认占满一行(占满整个文档流) 常见的块元素:p,h1--h6,ul li, ol li,div,hr,table. 2.行内 ...
- XAMPP/PHPnow/phpStudy安装使用对比
一.XAMPP 1.1 下载 下载地址:https://www.apachefriends.org/download.html 1.2 安装 双击下载的安装程序进行安装,界面如下图,都是典型的下一步下 ...
- linux重命名所有find查找到的文件/文件夹
一.说明 在某些时候我们想要将所有find命令查找到的文件或文件夹全都重命名,比如都加上.bak后辍 二.操作命令 find /dir -name "*pattern*" -exe ...