循环与闭包

    先看一个demo

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
for(var i = 0; i <= 5; i++){ setTimeout(function timer(){
console.log(i);
}, i*1000); } </script>
</body>
</html>

    结果会打印出什么? 相信大家都知道 答案是 6个6; 我们本意是打印出:0,1,2,3,4,5  但结果却是6个6, 为什么?首先解释一下为什么打印出6:这里涉及到延时函数的执行机制,虽然延时函数表明是i秒后执行,而i秒是相对与所有可执行代码执行完那一刻开始计时的,也就是等for循环结束之后,延时函数才开始执行。但此时 i= 6;所以会打印出6. 现在在解释一下为什么是6个6:很简单,for循环每执行一次就创建出一个延时函数,执行了6次,就会有6个延时函数。这6个延时函数共享一个作用域(本例中全局作用域) i又累加到6,所以会打印出6个6!!

    分析完整个过程,你知道问题出现在哪里吗?   有2个问题  1:每执行一次for循环,应该执行一次延时函数,但并没有。2:所有的延时函数共享一个作用域。

知道问题的地方,那就很好解决了:每循环一次,创建一个作用域 。 关键是如何实现“每循环一次,创建一个作用域”, 其实很简单,每循环一次,就立即执行一次延时函数,立即执行函数(IIFE)就派上用场了 它的原理很“粗暴”:每个延时函数都会将IIFE在每次迭代中创建的作用域 封闭起来。ok,修改一下我们的代码:

  

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
for(var i = 0; i <= 5; i++){
(function(){
setTimeout(function timer(){
console.log(i);
}, i*1000);
})(); } </script>
</body>
</html>

  在chrome中显示:

  咦??? 怎么还是6个6!!!  问题出在哪里?  其实很简单,仔细看一下,我们的IIFE只是一个什么都没有的空作用域(i是全局变量,处于全局作用域中) 它需要有自己的变量,用来在每个迭代中存储i的值   再来改进一下代码:

  

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
for(var i = 0; i <= 5; i++){
(function(){
var j = i;
setTimeout(function timer(){
console.log(j);
}, j*1000);
})(); } </script>
</body>
</html>

  在chrome中显示:

  把i值存进来,就可以实现 我们的预期了。到现在为止,代码已经是没有错误的了。但是,还可以优化:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
for(var i = 0; i <= 5; i++){
(function(i){
setTimeout(function timer(){
console.log(i);
}, i*1000); })(i)
} </script>
</body>
</html>

把i当作参数传进去,我们的代码就更完美了。

                                        2017-3-23  0:19

JavaScript---循环与闭包的更多相关文章

  1. JavaScript葵花宝典之闭包

    闭包,写过JS脚本的人对这个词一定不陌生,都说闭包是JS中最奇幻的一个知识点,  虽然在工作中,项目里经常都会用到~  但是是不是你已经真正的对它足够的了解~~ 又或者是你代码中出现的闭包,并不是你刻 ...

  2. 让你分分钟学会Javascript中的闭包

    Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...

  3. 深入理解javascript原型和闭包(4)——隐式原型

    注意:本文不是javascript基础教程,如果你没有接触过原型的基本知识,应该先去了解一下,推荐看<javascript高级程序设计(第三版)>第6章:面向对象的程序设计. 上节已经提到 ...

  4. javascript中的闭包、模块与模块加载

    一.前言 闭包是基于词法作用域(  和动态作用域对应,词法作用域是由你写代码时,将变量写在哪里来决定的,因此当词法分析器处理代码时,会保持作用)书写代码时所产生的自然结果,甚至不需要为了利用闭包而有意 ...

  5. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  6. javascript中的闭包解析

    学习javaScript已经有一段时间了,在这段时间里,已经感受到了JavaScript的种种魅力,这是一门神奇的语言,同时也是一门正在逐步完善的语言,相信在大家的逐步修改中,这门语言会逐步的完善下去 ...

  7. 《深入理解javascript原型和闭包系列》 知识点整理(转)

    深入理解javascript原型和闭包系列 对原型和闭包等相关知识的讲解,由浅入深,通俗易懂,每个字都值得细细研究. 一.一切都是对象 1. typeof操作符输出6种类型:string boolea ...

  8. 《深入理解javascript原型和闭包系列》 知识点整理

    深入理解javascript原型和闭包系列 对原型和闭包等相关知识的讲解,由浅入深,通俗易懂,每个字都值得细细研究. 一.一切都是对象 1. typeof操作符输出6种类型:string boolea ...

  9. JavaScript中的闭包理解

    原创文章,转载请注明:JavaScript中的闭包理解  By Lucio.Yang 1.JavaScript闭包 在小学期开发项目的时候,用node.js开发了服务器,过程中遇到了node.js的第 ...

  10. javascript作用域和闭包之我见

    javascript作用域和闭包之我见 看了<你不知道的JavaScript(上卷)>的第一部分--作用域和闭包,感受颇深,遂写一篇读书笔记加深印象.路过的大牛欢迎指点,对这方面不懂的同学 ...

随机推荐

  1. Tomcat内部结构及请求原理(转)

    Tomcat Tomcat是一个JSP/Servlet容器.其作为Servlet容器,有三种工作模式:独立的Servlet容器.进程内的Servlet容器和进程外的Servlet容器. Tomcat的 ...

  2. Uvalive 7037 The Problem Needs 3D Arrays(最大密度子图)

    题意:给一段子序列,定义密度:子序列中的逆序对数/子序列的长度 求这个序列的对大密度. 分析:将序列中的每个位置视作点,逆序对\(<i,j>\)之间表示点i与点j之间有一条无向边.所以就转 ...

  3. Selenium+Python常见定位方法

    参见官网:http://selenium-python.readthedocs.io/locating-elements.html 有多种策略来定位页面中的元素.你可以使用最适合你的情况.Seleni ...

  4. Autowire

    Field userService in com.demo.web.Controller.HomeController required a single bean, but 2 were found ...

  5. Django学习笔记之利用Form和Ajax实现注册功能

    一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面建一个forms.py的文件来存放 2 ...

  6. 20145331 《Java程序设计》第3周学习总结

    20145331 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 认识对象 •对象(Object):存在的具体实体,具有明确的状态和行为 •类(Class):具有相同属性和行 ...

  7. Jquery7 表单选择器

    学习要点: 1.常规选择器 2.表单选择器 3.表单过滤器 表单作为 HTML 中一种特殊的元素,操作方法较为多样性和特殊性,开发者不但可以使用之前的常规选择器或过滤器,也可以使用 jQuery 为表 ...

  8. 聊一聊HTML <!--…-->标签

    定义 注释标签用于在html源代码中插入注释.注释不会在浏览器上显示. 用法 根据定义的基本用法,代码如下 <!-- 这是一段注释,我不会显示在页面上 --> 浏览器的支持情况 所有浏览器 ...

  9. [BZOJ4653 区间]

    Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x ...

  10. Putting Apache Kafka To Use: A Practical Guide to Building a Stream Data Platform-part 1

    转自: http://www.confluent.io/blog/stream-data-platform-1/ These days you hear a lot about "strea ...