一、闭包(Closure)模糊概述

之前总觉得闭包(Closure)很抽象而且难理解,百度一下"闭包"名词,百度的解释是:“闭包是指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)”

看了半天,也没有看懂闭包是什么?以下将是我对闭包(Closure)的理解,如有错误欢迎指出

    二、普通函数、变量访问作用域

以上普通函数的调用fn被调用了两次,变量b却没有累加??

对于函数f1变量b在函数外部是不能访问的

如若实现局部变量b的累加,并且可以访问该怎么做呢?

    三、闭包(Closure)的清晰描述

(1)闭包(Closure)简单的可以理解成函数的嵌套,闭包就是能够读取其他函数内部变量的函数。

(2)变量长期驻留在内存中

以上可以看出,父函数f1中的变量b对于子函数f2是可访问的或者说是可见的,父函数f1调用一次,意味着变量b始终都是同一变量,f2中的b++,实现了对同一变量的自加,

对于子函数f2形成一个最简单的闭包(或者说函数f2维持着对外部作用域f1的引用,因此总可以访问f1作用域中的变量b)

    三、闭包在对象中应用

    四、解决获取标签索引问题

需求:当点击点击标签li时,获取标签li的内容及索引

 a.理想中的方案一<未使用闭包,未解决索引值问题>

效果:未解决获取到当前点击标签对应索引值,获取到的索引总是for循环完毕后的索引i

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>未使用闭包获取标签索引</title>
<script type="text/javascript">
window.onload=function(){
var oLi=document.getElementsByTagName('li');
for (var i = 0; i < oLi.length; i++) {
oLi[i].onclick=function(){//当点击li的时候,for循环已经执行完毕
alert(this.innerHTML+'index'+i);//总是i==5
}
};
}
</script>
</head>
<body>
<ul>
<li>AAA</li>
<li>BBB</li>
<li>CCC</li>
<li>DDD</li>
<li>EEE</li>
</ul>
</body>
</html>

b.解决方案二<使用闭包>代码如下:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>闭包解决获取标签索引问题</title>
<script type="text/javascript">
window.onload=function(){
var oLi=document.getElementsByTagName('li');
/*for (var i = 0; i < oLi.length; i++) {
oLi[i].onclick=(function(i){ //就已经存储到缓冲中
return function(){
alert(this.innerHTML+'index'+i);
}
})(i)
};*/
for (var i = 0; i < oLi.length; i++) {
(function(i){
oLi[i].onclick=function(){
alert(this.innerHTML+'index'+i);
}
})(i)
};
}
</script>
</head>
<body>
<ul>
<li>AAA</li>
<li>BBB</li>
<li>CCC</li>
<li>DDD</li>
<li>EEE</li>
</ul>
</body>
</html>

    五、一道思考题(for循环与setTimeout)

上述打印结果打印了10次10,而不是0~9

原因 当 console.log 被调用的时候,匿名函数保持对外部变量 i 的引用,此时 for循环已经结束, i 的值被修改成了 10.

为了打印结果是0~9,需要在每次循环时创建变量i的拷贝修改代码如下

或修改成如下

作者:Avenstar

出处:http://www.cnblogs.com/zjf-1992/p/5380456.html

关于作者:专注于前端开发、喜欢阅读

本文版权归作者所有,转载请标明原文链接

资料参考

http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

http://www.jb51.net/onlineread/JavaScript-Garden-CN/#function.closures

JavaScript闭包理解【关键字:普通函数、变量访问作用域、闭包、解决获取元素标签索引】的更多相关文章

  1. JavaScript闭包理解【关键字:普通函数、闭包、解决获取元素标签索引】

    以前总觉得闭包很抽象,很难理解,所以百度一下"闭包"概览,百度的解释是:“闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的 ...

  2. class 用法 函数变量的作用域

    函数变量的作用域 1. 函数体内声明的变量 2. 参数中的变量 没有赋值的 function fn(a){} 赋值的,值不是变量 function fn(a=45){} 赋的值为变量 function ...

  3. JavaScript 基础(五) 函数 变量和作用域

    函数定义和调用 定义函数,在JavaScript中,定义函数的方式如下: function abs(x){ if(x >=0){ return x; }else{ return -x; } } ...

  4. JavaScript 使用new关键字调用函数

    使用new关键字调用函数 test.js 代码如下 function Person(name, age, obj) { var o = new Object(); o.name = name; o.a ...

  5. 【追寻javascript高手之路02】变量、作用域知多少?

    前言 本来想把这个与上篇博客写到一起的,但是考虑到是两个知识点还是分开算了,于是我们继续今天的学习吧. 基本类型与引用类型 ECMAScript的的变量有两种类型: 基本类型(值类型):简单数据段 引 ...

  6. JavaScript学习笔记(八)——变量的作用域与解构赋值

    在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...

  7. JavaScript高级程序设计学习(三)之变量、作用域和内存问题

    这次讲的主要是变量,作用域和内存问题. 任何一门编程语言,都涉及这三个. 变量,比如全局变量,局部变量等,作用域,也分全局作用域和方法作用域,内存问题,在java中就涉及到一个垃圾回收的问题,由于ja ...

  8. 精读《javascript高级程序设计》笔记二——变量、作用域、内存以及引用类型

    变量.作用域和内存问题 执行环境共有两种类型——全局和局部 作用域链会加长,有两种情况:try-catch语句的catch块,with语句. javascript没有块级作用域,即在if,for循环中 ...

  9. JavaScript读书笔记(4)-变量、作用域和内存问题

    1.ECMAScript数据类型分为:基本类型值和引用类型值: ECMAScript中所有函数的参数都是按值传递的: 检查对象的类型:varible instanceof constructor Al ...

随机推荐

  1. 【转载】PhpStudy修改Apache的端口号

    phpStudy是一个PHP调试环境的程序集成包.该程序包集成最新的Apache+PHP+MySQL+phpMyAdmin+ZendOptimizer,一次性安装,无须配置即可使用,是非常方便.好用的 ...

  2. .NET 中的序列化 & 反序列化

    序列化:将对象的状态信息及类型信息,转换为一种易于传输或存储形式(流,即字节序列)的过程. 下图为序列化过程图示,图片来自微软官方文档: 反序列化:与序列化相反,将流转换为对象的过程. 常用的有二进制 ...

  3. 使用wubi安装ubuntu14.04出现的常见错误的解决办法

    花了一天的时间终于安装上了Ubuntu14.04,过程坎坷,是血泪史,开始报“cannot download the metalink and therefore the ISO”错误,解决后,又报“ ...

  4. EF实现增删改查

    从来没想到过能在这个上面翻车,感慨自学没有培训来得系统啊,废话不多说 ORM:对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一 ...

  5. 【mysql】2003-Can't connect to MySQL server (10060)

    使用navicat或者其他数据库管理工具连接mysql时出现2003-Can’t connect to MySQL server (10060)错误 可能造成出现的原因: 1.网络不通畅 2.mysq ...

  6. es6 语法 (Generator)

    { // 长轮询 let ajax=function* (){ yield new Promise(function(resolve,reject){ setTimeout(function () { ...

  7. SAP MM ME57 把PR转成PO

    SAP MM ME57 把PR转成PO 加入P3项目里,笔者负责采购和IM库存管理domain.采购环节里的PR转PO,客户global template里建议使用ME57或者在MD04里做.笔者在项 ...

  8. C# SharpMap的简单使用

    本文是利用ShapMap实现GIS的简单应用的小例子,以供学习分享使用.关于SharpMap的说明,网上大多是以ShapeFile为例进行简单的说明,就连官网上的例子也不多.本文是自己参考了源代码进行 ...

  9. Wu反走样算法绘制直线段

    Wu反走样算法 原理:在我看来,Wu反走样算法是在Bresenham算法基础上改进了一番,它给最靠近理想直线/曲线的两个点以不同的亮度值,以达到模糊锯齿的效果.因为人眼看到的是线附近亮度的平均值. M ...

  10. .net webapi 后台导出excel 申请付款单实例

    [HttpGet, AllowAnonymous] public void ExportSettlementPrint(string code) { FinSettlementModel settle ...