j**ascript 闭包详解

时间:2016.04.19 发布人:0110ROC

j**ascript 闭包详解

已解决问题

谷歌0110ROC用户在2016.04.19提交了关于“乔丹j**ascript 闭包详解”的提问,欢迎大家涌跃发表自己的观点。目前共有1个回答,最后更新于2024-11-04T21:04:17。希望大家能够帮助她。

详细问题描述及疑问:期待您的答案,你就是当代的活雷锋,太感谢了 !

希望以下的回答,能够帮助你。

第1个回答

用户名:z305vdk710  

看了一下网上闭包的概念及文章,对于这个问题,自己做一个梳理吧。

问:闭包是什么?
答:闭包是指在J**aScript中,**函数总是可以访问其所在的外部函数中声明的社根果伤括额每参数和变量,即使在东分其外部函数被返回(寿命终结)了或愿保之后。

这个是我自身第一次碰到闭包的问题

<!DOCTYPEh**TML><html><head><metacharset="utf守纸-8"/><title>闭包循环问题</title><styletype="text/css">p{backg亲备呢是松千犯河庆现round:#ccc;width:300px;height:100px;}</style></head><bod九斗约香富烟击卫y><pid="p0">段落0</p><pid="p1">段落1</p><pid="p2">段落2</p><pid="p3">段落3</p><pid="p4">段落4</p><scripttype="text/j**ascript">for(vari=0;i<5;i++){document.getElementById("p"+i).onclick=function(){alert(i);//访问了父函数的变量i,闭包};};</script></body></html>

如果你以前没这么用过的话,估计也会认为单击某个段落就会出这个段落相应的编号0,1,2,3,4。但实际上是都是出5;

对于这个问题网上已经有药衡收空味粮促制良很多讨论的博客了,他们给出了很多方法去实现出对应的编号。

解决方法1:将变量i保存在对应的语蒸门官阶宽告律段落的某个属性上

varpAry=document.getE旧续脚洋食赶叫司行理lementsByTagName("p");for(var别肉田度师飞扩服i=0;i<5;i++){副阿角牛判露形田玉pAry[i].no增绿总乎策苗难向放附试=i;pAry[i].酸径川还onclick=function(){alert(***.no状微曾额);}};

解决方之飞字值钱之认法2:加一层闭包,i以函数参数形式传递给内层函数

varpAry=document.getElementsByTagName("p");for(vari=0;i<5;i++){给并丝聚pAry[i].no=i;pAry[i].onclick=function(){alert(***.no);}};

对于这个**生的闭包官问题,网上的说法是“变量i是以指针或者变量地址方式保存在函数中”;好吧,都和指针扯上关系了。。。。那就再探索一下吧。

探索1,返回的都是10而不是而是

(functiontest(){vartemp=10;for(vari=0;i<5;i++){象道独侵准费此最巴代document.getElementById("p"+i).onclick=function(){alert(temp);//访问了父函数的变量temp,闭包}};temp=20;})();

探索2,返回一次10,接下去返回的都是20

(functiontest(){vartemp=10;for(vari=0;i<5;i++){document.getElementById("p"+i).onclick=function(){alert(temp);//访问了父函数的变量i,闭包}if(i===1){alert(temp);}};temp=20;})();

由探索的1、2,可以得出结论:函数**访问了与函数同级的变量,那么该变量是常驻内存的。访问该变量实质上是访问的是变量的地址;

接着,又看了一篇关于“JS闭包中的this对象”的文章,继续来讨论一下,this这个问题吧。

//js闭包this对象1varname='TheWindow';varobject={name:'MyObject',getNameFunc1:function(){//return***.name;console.log(this);//objectreturnfunction(){//闭包,访问的便是全局变量的了,this指windowsconsole.log(this);//windowsreturn***.name;//TheWindow}},getNameFunc2:function(){return***.name;//访问的是object},aa:function(){alert(22);}};alert(object.getNameFunc1()());//出“TheWindow”

问:那么为什么匿名函数没有取得其包含作用域的this对象呢?
答:每个函数在被调用时都会自动获取两个特殊变量:this和arguments。**函数在搜索这两个变量时,指挥搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量。
不过通过下面的代码可以做到这一点(直接访问外部函数中的变量):

//js闭包this对象2varname='TheWindow';varobject={name:'MyObject',getNameFunc:function(){varthat=this;console.log(this);//输出的是objectreturnfunction(){console.log(this);//输出的仍然是Windowsreturn***.name;};}};alert(object.getNameFunc()());//出“MyObject”

不同之处在于把this对象赋给了一个that变量,即使在函数返回之后,that也仍然引用这object,所以会返回object。
写了那么多闭包的东西,那也顺便再说一下闭包有神马用处吧;不然,一直捣乱那闭包可真是一个不好的家伙呢。

看这样一典型的闭包的例子:

functionA(){vara=1;functionB(){returna;};returnB;};varC=A();//C取得A的子作用域B的访问接口console.log(C());//1C能访问到B的父级作用域中的变量a

只要其他作用域能取到子作用域的访问接口,那么其他作用域就有方法访问该子作用域父级作用域的变量了。这样的话,如果以后需要访问某个函数里面的值得时候,就大大的有用咯。

这些上面的很多代码其实也都是网上找的,我也只是把自己理解的,看的过程总结一下吧。