js闭包

来源:互联网 发布:邮箱域名怎么写 编辑:程序博客网 时间:2024/06/05 05:10

js闭包-----浅谈



接触js也有一段时间了,最近看了一些关于闭包的问题,不是很理解,就决定花一点时间去弄懂它。于是乎在网上查阅了大量的资料,看了很多例子。接下来简单的讲一下我对闭包的理解。
首先我们学一个知识点之前,肯定要思考的一个问题就是我们为什么要去学它?它到底有什么用?能解决什么问题?

什么是闭包?

“官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很少有人能直接看懂这句话,因为他描述的太学术。我想用如何在Javascript中创建一个闭包来告诉你什么是闭包,因为跳过闭包的创建过程直接理解闭包的定义是非常困难的。看下面这段代码:
function a(){ var i=0; function b(){ alert(++i); } return b;}var c = a();c();
这段代码,有两个特点:
1.在函数a里面嵌套了一个函数b
2.函数a返回了函数b

这样就是一个简单的闭包。
a函数里面定义了一个局部变量i ,因为这是一个局部变量,一般会在函数执行完毕之后,被销毁,但是由于i在函数b中被引用,
而函数b又被return,被赋值给了全局变量c。所以当函数a执行完之后,i不会被销毁。
你可以在上面的代码下继续执行函数c就会弹出2,3,4,5.因为此时变量i依然存在而且保留着上一次执行完之后的数据。

闭包有什么用?

相信看了上面的一个例子,我们就能知道得到这个答案。
闭包能在函数外部,访问函数的局部变量,能使变量始终存在内存中。
再以一个简单的例子说明一下:
var ulo = document.getElementById('ulo');var lio = ul.getElementsByTagName('li');for(var i = 0;i<10;i++){ lio.addEventListener('click',function(){      alert(i);   })}

假设html为:
<ul id="ido">   <li></li>   ......</ul>


上面的js代码为10个li绑定了事件,但是真正执行时,会发现无论我点哪一个li结果都会alert(9);
因为当我们点击li时这段代码已经执行完一遍了,此时的i已经是9了,所以当我们点击任何一个li都会弹出9。
解决方法:
var ulo = document.getElementById('ulo');var lio = ulo.getElementsByTagName('li');for(var i = 0;i<10;i++){  !function(i){     lio.addEventListener('click',function(){       alert(i)    })  }(i)}
此时的i不会去向外部的i去获取(因为此时外部的i值已经是执行完之后的值了)。而是通过闭包保存该i值,这个值就是当时的i值,当点击时,会向即时函数获取i值,也就是被保存起来的那个i值。

js的垃圾回收机制

在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。
所以闭包的使用要慎重,要在不使用时,释放变量,防止内存泄漏。


好了,这就是我现阶段对于闭包的理解,可能还有些偏差,也不是很全面,不喜勿喷,我也会在之后做相应的更新。希望能对一些小伙伴有所帮助。
1 0
原创粉丝点击