在使用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-8ATM

    源代码: import java.util.Scanner;interface fangfa{ public void show();public void qukuan();public void ...

  2. slf4j+log4j的使用

    maven依赖引入 <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j1 ...

  3. [DB] - Mysql创建定时任务

    mysql支持定时任务的创建,要求mysql服务器开始定时任务调度. 1. 查看是否开启定时任务执行 SHOW VARIABLES LIKE 'event_scheduler'; // OFF表示没有 ...

  4. Jsp——response对象

    <%@ page language="java" contentType="text/html; charset=UTF-8" import=" ...

  5. redis主从切换的集群管理

    集群配置最少需要三台机器,那么我就三台虚拟机,三台虚拟机分别安装同样的redis的环境ip分别:192.168.9.17 (redis sentinel 集群监控)192.168.9.18 (redi ...

  6. 《Shell脚本学习指南》学习笔记之变量、判断和流程控制

    变量 定义变量 可以使用export和readonly来设置变量,export用于修改或打印环境变量,readonly则使得变量不得修改.语法: export name[=word] ... read ...

  7. Debian/Ubuntu安装Oracle客户端TNS

    本文作为新手在Linux上部署Java程序的必经之路的Oracle客户端配置,请高手绕道. 确定服务器版本 首选确定你的Oracle服务器版本,以便下载相应的客户端.查看的sql如下: select ...

  8. HTML 5入门知识——Drag

    HTML 5拖放 拖放的步骤: 1.对象元素的draggable属性设置为true,还需要注意的是a元素和img元素必须指定href. 2.编写与拖放有关的事件处理代码: DataTransfer对象 ...

  9. 3407: [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题

    3407: [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit:  ...

  10. Alamofire源码解读系列(六)之Task代理(TaskDelegate)

    本篇介绍Task代理(TaskDelegate.swift) 前言 我相信可能有80%的同学使用AFNetworking或者Alamofire处理网络事件,并且这两个框架都提供了丰富的功能,我也相信很 ...