闭包

一。定义:当内部函数被保存在外部时,会生成闭包。闭包会导致原有作用域链不释放,造成内存泄漏。

<script type="text/javascript">
		function a(){
			function b(){
				var bbb=234;
				document.write(aaa); 
			}
			var aaa=123;
			return b;  //b被抛到了全局范围,抛出的是地址,b不执行
		}
		var glob = 100;
		var demo = a();
		demo(); //打印出了网页的123
</script>

页面的效果:
123


 

 这张图很好的诠释了作用域链,也形象的表示了闭包未释放内存,也有利于理解下面将要讲解的闭包的作用。

二。闭包的作用:

1)实现共有变量。例如,函数累加器

<script type="text/javascript">
		function a(){
			var num = 100;
			function b(){
				num++;
				console.log(num);
			}	
			return b;
		}
		var demo = a();
		demo();  //101
		demo();  //102
</script>


AO a {        num : 102      }

他的累加形象图可以参考 一 中的手绘图,形象的描述了没有释放a函数的内存,从而导致a函数每次的执行期上下文都被更新保存到b函数的定义阶段。

2)可以做缓存(存储结构)

这个就类似上面的例子了,都是基于他没有释放内存。

3)可以实现封装,属性私有化。

例子,Person(),这是个高级应用的例子,详情参考另外一篇博客。这里不做详细分析。

4)模块化开发,防止污染全局变量。

这个也在下面的博客中,详情参考博客  命名空间。

三。在这里,还是用一个有趣的实例给大家举例一下

请看代码如下:

<script type="text/javascript">
		function test(a,b,c,d){
			var arr=[];
			for(var i = 0;i < 10;i++){
				arr[i] = function(){
					document.write(i+" ");
				}
			}
			return arr;	
		}
		var myarr = test();
		for(var j = 0;j < 10;j++){
			myarr[j]();
		}
		
	</script>

大家猜一下上面的代码在网页上是什么呈现呢?你可能会猜想 1 2 3 4 5 6 7 8 9 10 是吗?

如果是这样的话,那请你再仔细推理一下,找一下其中的逻辑错误。

好了,让我们看一下页面效果:

 是不是有点惊讶呢。惊讶为什么是10个 10 。下面我给大家解释一下:

在这里非常典型的用到了闭包的知识。在第一个for循环中,有一个arr赋值语句。变量声明,声明提升。这个赋值语句是一个函数引用,把一个函数赋值给了一个变量(这是函数表达式)。注意了, = 符号 前面的arr[i] 会改变,而document.write()这个我们之前学过,他直接改变了页面结构,return arr 相当于把输出值直接抛到了函数体的外部,函数会保存在外部,这就直接形成了一个闭包。在 = 赋值语句执行的时候才会考虑这样一个问题: i 是什么。

形成了闭包,就有10个不同的函数,每个函数执行时都会产生一个独一无二的执行期上下文(这个知识点不懂的话,大家可以参考我之前写过的预编译和作用域链两篇文章的开头部分),每个函数相互独立,但是注意他们的函数内容是相同的。

继续读代码,读到第二个for循环大家注意一下。myarr[i]();  这里执行的时候,在这里索取 i  ,而此时 i 已经变成了 10.  

相同的练习题,工大家练习一下

 

选A

打印 2  2

打印 2 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值