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
- js闭包示例
- JS 闭包 计数器
- js闭包
- js 闭包
- js闭包
- js闭包
- js闭包
- js 闭包
- js 闭包
- js闭包
- js闭包
- (function (){})(); JS 闭包
- JS 闭包应用
- js闭包
- JS闭包
- JS 闭包随笔
- js闭包
- js 闭包
- 音视频聊天开发: 2 视频编解码并显示
- 如何使用JDBC实现数据访问对象层(DAO)
- 解决vs2005使用调试功能就报错的问题
- php中的命名空间namespace
- sguap 所接触到的名称
- js闭包
- html全屏
- 十六进制数据与字符串的相互转换
- jQuery+ThinkPHP+Ajax实现即时消息提醒功能
- 计算机操作系统
- jdk8新特性
- IE8兼容问题
- 音视频聊天开发: 3 UDP的简单封装
- Jquery EasyUI DataGridView(easyui分页列表)