认识和使用闭包

8人阅读 评论(0) 收藏 举报
分类:

认识闭包

什么是闭包,简单的说就是函数套函数,内部函数如果能访问到外部函数中声明的私有变量、参数或者其他内部函数,在外部函数的外部调用这个内部函数,这就是闭包,一个动态概念。

最简单的例子:

非闭包:function f(x){
var a=x;
var b=a;
a++;
return b;
}
var c=f(5);

alert(c());

结果为5


闭包function f(x){
var a=x;
var b=function(){
return a;
}

a++;
return b;
}
var c=f(5);

alert(c());

结果为6

这两段带码的区别就在于红色部分,在蓝色部分彻底展现出来,闭包函数在执行return的时候执行了

function(){

    return a;

},结果发现a已经a++了,(狗子!你变了,不过爸爸还是原谅你),就酱,b的值也随着a的变化而更新。



非闭包函数直接把a赋值给b,也就是说把b的值已经写死了,直接return写死的值,GOODGAME。。。

所以,一分长一分强啊兄得。。。还不好好锻炼锻炼。


闭包是函数运行期中的一个动态环境,与函数的静态性截然不同(想象不来,反正书上就这么说的)

总结一句话:闭包的作用就是防止激活对象被正常的销毁。(怎么理解呢,var b=function(){
return a;
}这个闭包体造就了b和a之间的联系,在非闭包函数中如果直接var b=a;则赋值完成后b和a之间再就没啥联系了,从此分道扬镳,前面一只大雁飞啊飞,后面一只大雁追啊追,追上之后咔咔一顿锤,锤完之后谁也不认识谁。。。言归正传,在闭包体中,因为是一个函数嘛,只要我不使用这个闭包体函数,b和a之间那种潜在的联系一直会存在,直到var b=function(){
return a;

}这一部分被执行,所以a在外边随便混,b对a的动态变化一直保持关注。闭包不要过多使用,多占内存

下面拿书上的一个例子来说

function f(x){
var a=[];//新建一个临时数组
for(var i=0;i<x.length;i++){
var temp=x[i];
// 临时存储每个数组元素
a.push(
// 在数组中添加下面函数返回值
function(m,n){
// 给匿名函数传递参数
return function(){
// 返回另一个匿名函数
alert(m+' '+x[n])
// 弹出一个参数m(静态的)和x数组中的一个数组元素x[n](动态的)【这就是关键点,等下对比说明一下精妙之处在哪里】
}
}(temp,i)
// 将参数temp和i传递给函数,形成了一个闭包体
);
// 随着for循环i的递增,数组中的值以闭包体函数的形式被重新存储在a数组中
}
return a;
}
(function e(){
var a=f(['a','b','c']);
// 调用闭包函数
for(var i=0;i<a.length;i++){
// 循环执行闭包体
a[i]();
}
})();

这个闭包函数实现了动态存储变量所有变化的值。

下面讲一下这个闭包函数的错误写法(我就这么想的,然而。。。。。。it's wrong)

<script>
//现在我们分析一下这个闭包函数到底错在哪儿
function f(x){
var a=[];//新建一个临时数组
for(i=0;i<x.length;i++){
//把数组里的元素循环赋值给temp
var temp=x[i];
a.push(
function(){
alert(temp+' '+x[i]);
}//问题就出在这里,理想情况:当i为0的时候,闭包里的temp和x[i]为a
// 当i为2的时候闭包里的temp和x[i]为b,i为3也如此,按道理来说闭包不就是这么用的嘛,其实思路是对的,只是有一个问题,闭包体会把参数动态更新最新的值,也就是说只要闭包函数一经激活,闭包体就开始干活了,它会把temp更新到最新值,把i更新到最新值,你的第一圈for循环开始的时候,temp已经是c,i已经是3了(i=3时不执行循环体而已,但i已经更新到3了),所以第一圈循环与第二第三圈循环在执行相同的操作,x[3]也就是数组第四个元素未定义的,于是报错,这种感觉就像是杀猪(村里来的不要介意),当听说有猪要杀(闭包函数要执行),不管猪来没来(函数执行没执行),先磨刀(更新变量)嘛,磨刀石上(闭包体上)磨啊磨(动态更新啊更新),当猪来的时候,迎接它的是最快的刀和最温暖的双手,一库~。
);
}
return a;
}
(function e(){
//执行函数e,把
var a=f(['a','b','c']);//执行闭包函数
for(var i=0;i<a.length;i++){
//循环读取闭包体并立即执行
a[i]();
}
})();
</script>


查看评论

如何有效的使用闭包

【译】如何有效地使用闭包 2016-05-23 JavaScript 译者:Jason(https://l-movingon.github.io/posts/2016-05-06-...
  • qq_28489043
  • qq_28489043
  • 2016-08-16 13:00:40
  • 359

JS的闭包 (一)——为什么要用闭包

最近在学习js时,遇到一个比较难的概念,闭包,在这里与大家分享一下我的学习心得。使用闭包,我们一定要明白为什么,何时使用闭包。 在网上查阅资料,阮一峰的博客里面介绍道: 我们知道js的函数内部局部...
  • dgqJs
  • dgqJs
  • 2016-12-05 10:57:02
  • 1537

什么是闭包,闭包的作用与好处是什么,何时使用闭包,对闭包的改进

闭包:外部函数定义的内部函数就是闭包。 闭包的作用及好处:闭包给访问外部函数定义的内部变量创造了条件。也将关于函数的一切封闭到了函数内部,减少了全局变量,这也是闭包的真实含义。 与普通函数...
  • wzw_mzm
  • wzw_mzm
  • 2017-02-24 14:11:23
  • 2895

闭包用法:经典案例

闭包用法:经典案例 学习一样技能,最终是想把它投入运用。我们从JS函数的最基础用法,一直研究到作用域链、闭包,这个过程消耗了我们大量的心血,那么闭包到底能用在哪些场景里面呢?下面将使用逐个枚举的方式...
  • ninejj
  • ninejj
  • 2015-04-08 11:02:54
  • 1265

Swift 函数,闭包使用

一.Swift中的函数 1. 函数的定义与使用 在介绍Swift中的函数之前,我想用Objective-C中的一个简单的加法函数来作为引子,然后类比着实现一下Swift中相同功能的函数。关...
  • zhangjitao_boke
  • zhangjitao_boke
  • 2016-01-19 20:44:09
  • 1117

javascrpt为什么要用闭包

javascript 为什么要使用匿名函数 或者说 匿名闭包 检举|2012-04-27 21:54 zjlahbf | 分类:JavaScript | 浏览532次 (function () {...
  • yangnuowei88
  • yangnuowei88
  • 2013-08-29 18:09:45
  • 4688

记python中的闭包应用

今天我们来看一下函数的闭包(closure)。python中学到高级语法,闭包是逃不开的话题,无论是高阶函数还是装饰器等,不理解闭包会寸步难行。     来看代码 def count(): ...
  • Rubik_Wong
  • Rubik_Wong
  • 2016-12-15 21:29:52
  • 556

Swift中的逃逸闭包的理解

逃逸闭包的书面定义一个传入函数的闭包如果在函数执行结束之后才会被调用,那么这个闭包就叫做逃逸闭包。对定义的理解通过定义我们知道,逃逸闭包首先是一个闭包(感觉有点废话),但是逃逸闭包又不是普通的闭包,因...
  • shenjie_xsj
  • shenjie_xsj
  • 2017-12-18 17:54:56
  • 410

Swift使用闭包表达式

Swift中的闭包表达式很灵活,其标准语法格式如下:{ (参数列表) ->返回值类型 in    语句组}其中,参数列表与函数中的参数列表形式一样,返回值类型类似于函数中的返回值类型,但不同的是后面有...
  • tonny_guan
  • tonny_guan
  • 2014-09-04 20:34:07
  • 5457
    个人资料
    等级:
    访问量: 31
    积分: 72
    排名: 157万+
    文章分类
    文章存档