在使用for循环的时候,假如需要在循环体中添加一个匿名函数处理其他的事情,那么,在这个匿名函数内,如果需要用到对应的i,因为闭包的缘故,循环体循环结束后才返回i,所以i最终为最后一次++的数值。
 

闭包即函数有权访问另一函数的局部变量,常用方法为在函数内部创建另一个需要引用这个函数内部变量的函数。
 
解决方式1

通过匿名函数传参,因为匿名函数取得参数是每次for循环里的i,所以每次打印的值为0,1,2,......
 
匿名函数自我执行的方法是,在函数体外套一对圆括号,形成一个表达式,在圆括号后再加另一个圆括号,里面可传参数。此方法即IIFE,又叫立即执行函数表达式。
写到这里,还需要说一下函数声明和函数表达式的区别:
1.函数声明必须有标识符,即函数名;
2.函数声明存在变量提升;
3.函数声明不能出现在循环,判断、try、with等语句的代码块中;
 
 
解决方式2

此方法和上述方法有异曲同工之妙,也是在匿名函数体外部取到了循环体中的i;

 
在JS中,每一个函数被调用的时候都会创建一个执行上下文,在该函数内部定义的变量和函数只能在该函数内部被使用,正是因为这个上下文,使得我们在调用函数的时候能创建一些私有变量。

为什么a()()两次打印都是1,是因为每次执行a()()的时候都给a重新赋值1,而b()/c()执行的只是a return出来的匿名函数;

为什么报错?
因为在javascript解析代码时,当遇到function关键字时,会默认把它当作一个函数声明,而不是函数表达式,如果没有显示的表达成函数表达式,就报错。因为函数声明需要一个函数名,而上面的代码中函数没有函数名。(在执行到第一个左括号时报错)

为什么在加了函数名之后,依然报错?
在一个表达式后面加上括号表示立即执行,而在一个语句后加上括号,该括号和之前的语句完全不搭边,而只是一个分组操作符,用来控制运算中的优先级,当js解析到括号时,发现里面为空,所以报错。(在执行到第二个右括号时报错)
 
因为在js中括号内部不能为语句,所以js解析到括号时,紧接着发现了function关键字,所以自动把括号内的语句当作表达式而不是函数声明。
所以,立即执行函数,你可以这么写:

而上面我们用立即执行函数加闭包,取到了循环体中的i;可见合理利用立即执行函数加上闭包,还能保存变量的状态。
在模块化中,也可以用立即执行函数来处理模块化,可以减少全局变量造成的空间污染,构造更多的私有变量。

通过取父级for循环的i来理解闭包,iife,匿名函数的更多相关文章

  1. js 取父级 页面上的元素

    var bb=window.opener.frames["contentIframe"].document.all["my:费用类别"][0].value; / ...

  2. Jquery-获取父级元素parent

    1. parent([expr]): 获取指定元素的所有父级元素 <div id="par_div"><a id="href_fir" hre ...

  3. Handlebars.js循环中索引(@index)使用技巧(访问父级索引)

    使用Handlebars.js过程中,难免会使用循环,比如构造数据表格.而使用循环,又经常会用到索引,也就是获取当前循环到第几次了,一般会以这个为序号显示在页面上. Handlebars.js中获取循 ...

  4. 使用jQuery+huandlebars循环中索引(@index)使用技巧(访问父级索引)

    兼容ie8(很实用,复制过来,仅供技术参考,更详细内容请看源地址:http://www.cnblogs.com/iyangyuan/archive/2013/12/12/3471227.html) & ...

  5. 巧用javascript对象属性,向事件绑定的匿名函数内传递循环控制变量的值

    遇到一个需要向匿名函数传递循环控制变量的问题,我受到园子里这篇文章的启发[笔记]js获取当前点击元素的索引,解决了这个问题.现在把代码贴出来,以防止自己忘记. if ($('#labModal').l ...

  6. JsRender实用教程(tag else使用、循环嵌套访问父级数据)

    前言 JsRender是一款基于jQuery的JavaScript模版引擎,它具有如下特点: ·  简单直观 ·  功能强大 ·  可扩展的 ·  快如闪电 这些特性看起来很厉害,但几乎每个模版引擎, ...

  7. Js跨域、父级窗口执行JS赋值、取值,更改元素

    网站域名: A:http://www.xxoo.com/a.html B:http://www.aabb.com/b.html B网站嵌套与A网站(A的a中的Iframe指向B中的b)b要让父级a页面 ...

  8. 深入理解定位父级offsetParent及偏移大小

    前面的话 偏移量(offset dimension)是javascript中的一个重要的概念.涉及到偏移量的主要是offsetLeft.offsetTop.offsetHeight.offsetWid ...

  9. Jquery 父级元素、同级元素、子元素

    prev():获取指定元素的上一个同级元素(是上一个哦). prevAll():获取指定元素的前边所有的同级元素. find():查找子元素方式 next(): 获取指定元素的下一个同级元素(注意是下 ...

随机推荐

  1. Java编程规范(一)

    最近在看一本有关Java编程规范的书,书中精炼阐述了使用java语言时应该遵循的一些原则.接下来的一段时间我将在这里总结我的学习内容,也希望这一系列文章能够对有需要的人有所帮助. 不考虑任何编码规范的 ...

  2. iOS 手机摇一摇功能

    调用手机摇一摇功能其实很简单,在你调用的控制器的 viewDidLoad方法里调用 [UIApplication sharedApplication].applicationSupportsShake ...

  3. 不恰当的update语句使用主键和索引导致mysql死锁

    背景知识: 截至目前,MySQL一共向用户提供了包括DBD.HEAP.ISAM.MERGE.MyIAS.InnoDB以及Gemeni这7种Mysql表类型.其中DBD.InnoDB属于事务安全类表,而 ...

  4. C# Windows 异步线程

      Task t = new Task(new Action(() =>                     {                         //推送产品         ...

  5. 【Java基础】反射机制

    反射 反射可以使我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码链接.反射允许我们在编写和执行时,使我们的代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类 ...

  6. List实现行转列的通用方案

    最近在做报表统计方面的需求,涉及到行转列报表.根据以往经验使用SQL可以比较容易完成,这次决定挑战一下直接通过代码方式完成行转列.期间遇到几个问题和用到的新知识这里整理记录一下. 阅读目录 问题介绍 ...

  7. ci公共模型类

    我们都知道,操作数据库的方法都写在模型中.但是一般情况下,一张表往往至少对应4个操作,也就是所谓crud.那么如果20张表,所对应的模型方法,就达到了80个,重复的操作显然这已经是一个体力活儿. 那么 ...

  8. loadrunner入门篇-Vuser发生器

    Vuser 发生器(Visual User Generator,VuGen),主要通过捕获客户端向服务器发送的HTTP请求,将这些请求录制成脚本,在回放时将捕获的HTTP请求再次发送,以达到模拟客户行 ...

  9. Extjs中grid前端分页使用PagingMemoryProxy【二】

        在项目中遇到Grid前端分页,本人也是刚接触extjs没多久,为了实现效果,一直找了很久才实现出来,对于代码中的一些也不能详细的说明出来, 不知道能不能帮助到遇到同样问题的朋友,所以将例子代码 ...

  10. [干货来袭]C#7.0新特性(VS2017可用)

    前言 微软昨天发布了新的VS 2017 ..随之而来的还有很多很多东西... .NET新版本 ASP.NET新版本...等等..太多..实在没消化.. 分享一下其实2016年12月就已经公布了的C#7 ...