js闭包详解
闭包(closure
)是Javascript
语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
闭包的特性
闭包有三个特性:
1.函数嵌套函数
2.函数内部可以引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
闭包的定义及其优缺点
闭包
是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量
闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
闭包是javascript
语言的一大特点,主要应用闭包场合主要是为了:设计私有的方法和变量。
一般函数执行完毕后,局部活动对象就被销毁,内存中仅仅保存全局作用域。但闭包的情况不同!
嵌套函数的闭包
function aaa() { var a = 1; return function(){ alert(a++) }; } var fun = aaa(); fun();// 1 执行后 a++,,然后a还在~ fun();// 2 fun = null;//a被回收!!
闭包会使变量始终保存在内存中,如果不当使用会增大内存消耗。
javascript
的垃圾回收原理
(1)、在javascript
中,如果一个对象不再被引用,那么这个对象就会被GC
回收;
(2)、如果两个对象互相引用,而不再被第3
者所引用,那么这两个互相引用的对象也会被回收。
使用闭包的好处
那么使用闭包有什么好处呢?使用闭包的好处是:
1.希望一个变量长期驻扎在内存中
2.避免全局变量的污染
3.私有成员的存在
一、全局变量的累加
var a = 1; function abc(){ a++; alert(a); } abc(); //2 abc(); //3
二、局部变量
function abc(){ var a = 1; a++; alert(a); } abc(); //2 abc(); //2
那么怎么才能做到变量a既是局部变量又可以累加呢?
三、局部变量的累加
function outer(){ var x=10; return function(){ //函数嵌套函数 x++; alert(x); } } var y = outer(); //外部函数赋给变量y; y(); //y函数调用一次,结果为11,相当于outer()(); y(); //y函数调用第二次,结果为12,实现了累加
函数声明与函数表达式
在js中我们可以通过关键字function
来声明一个函数:
function abc(){ alert(123); } abc();
我们也可以通过一个"()"来将这个声明变成一个表达式:
(function (){ alert(123); })(); //然后通过()直接调用前面的表达式即可,因此函数可以不必写名字;
四、模块化代码,减少全局变量的污染
var abc = (function(){ //abc为外部匿名函数的返回值 var a = 1; return function(){ a++; alert(a); } })(); abc(); //2 ;调用一次abc函数,其实是调用里面内部函数的返回值 abc(); //3
五、私有成员的存在
var aaa = (function(){ var a = 1; function bbb(){ a++; alert(a); } function ccc(){ a++; alert(a); } return { b:bbb, //json结构 c:ccc } })(); aaa.b(); //2 aaa.c() //3
六.使用匿名函数实现累加
//使用匿名函数实现局部变量驻留内存中,从而实现累加 function box(){ var age = 100; return function(){ //匿名函数 age++; return age; }; } var b = box(); alert(b()); alert(b()); //即alert(box()()); alert(b()); alert(b); // function () { // age++; // return age; // } b = null; //解除引用,等待垃圾回收
过度使用闭包会导致性能的下降。函数里放匿名函数,则产生了闭包
七、在循环中直接找到对应元素的索引
window.onload = function(){ var aLi = document.getElementsByTagName('li'); for (var i=0;i<aLi.length;i++){ aLi[i].onclick = function(){ //当点击时for循环已经结束 alert(i); }; } }
八、使用闭包改写上面代码
window.onload = function(){ var aLi = document.getElementsByTagName('li'); for (var i=0;i<aLi.length;i++){ (function(i){ aLi[i].onclick = function(){ alert(i); }; })(i); } };
九.内存泄露问题
由于IE
的js
对象和DOM
对象使用不同的垃圾收集方法,因此闭包在IE
中会导致内存泄露问题,也就是无法销毁驻留在内存中的元素
function closure(){ var oDiv = document.getElementById('oDiv');//oDiv用完之后一直驻留在内存中 oDiv.onclick = function () { alert('oDiv.innerHTML');//这里用oDiv导致内存泄露 }; } closure(); //最后应将oDiv解除引用来避免内存泄露 function closure(){ var oDiv = document.getElementById('oDiv'); var test = oDiv.innerHTML; oDiv.onclick = function () { alert(test); }; oDiv = null; }
转:http://segmentfault.com/a/1190000000652891
js闭包详解的更多相关文章
- js 闭包 详解
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包的特性 闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数 ...
- js闭包详解-转自好友trigkit4
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包的特性 闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数 ...
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- Python闭包详解
Python闭包详解 1 快速预览 以下是一段简单的闭包代码示例: def foo(): m=3 n=5 def bar(): a=4 return m+n+a return bar >> ...
- Swift 中的Closures(闭包)详解
Swift 中的Closures(闭包)详解 在Swift没有发布之前,所有人使用OC语言编写Cocoa上的程序,而其中经常被人们讨论的其中之一 -- Block 一直备受大家的喜爱.在Swift中, ...
- PHP中的闭包详解
PHP闭包(Closure)使用详解 作者: 字体:[增加 减小] 类型:转载 时间:2013-05-02我要评论 本篇文章介绍了,PHP闭包(Closure)的使用介绍,需要的朋友参考下 不知不 ...
- Node.js npm 详解
一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...
- Vue.js项目详解
还是以Blog项目来讲解,最近我本人利用闲暇时间,以博客作为参考学习一些新的技术并尝试之前没有尝试过的思路来玩玩. 技术看似枯燥,但是带有一个目的来学,你会发现还是蛮有趣的. 主要实践的就是前后端分离 ...
- JS 面向对象详解
面向对象详解1 OO1.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
随机推荐
- BZOJ1864[ZJOI2006]三色二叉树[树形DP]
1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 773 Solved: 548[Submit][Status] ...
- url编码base编码解码十六进制
0x25346425353425343525333525343325366125343525373725346425353125366625373825346425343425363725346225 ...
- Android保存ArrayList至SharedPreferences
保存ArrayList至SharedPreferences 其中ArrayList中每个元素为String List<String> environmentList = new Array ...
- c#匿名类,匿名对象
何谓匿名类,其实本质和普通定义的类一样,只不过是由系统的编译器来完成的,首先举个例子. 一般情况 //声明一个类,包含贴别多的字段 public class Person() { public str ...
- git中的版本回退
git版本回退有两种情况,一种是从本地版本库中(head区)回退到某个版本,可以用命令 git reset --hard head^ 或git reset --hard head~x ,head指的是 ...
- http协议(八)请求首部字段
请求首部字段 定义:请求首部字段是从客户端到服务器发送请求报文中所使用的字段,里面包含了附加信息.客户端信息以及对响应内容相关的优先级等内容 1.Accept 通知服务器用户代理可处理的媒体类型及媒体 ...
- 十个节省时间的MySQL命令
十个节省时间的MySQL命令 2011-02-23 16:07 黄永兵 译 IT168 字号:T | T 编者在工作中积累起来了一些MySQL命令行客户端技巧,这些技巧或多或少会帮助您节省大量的时间. ...
- Jquery 数组操作
1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限, ...
- CSS3 动画效果带来的bug
css3 动画效果比如transition:all 2s linear;这种用来计算及时的物体坐标的话会带来一定的问题 比如把一个DIV从A点移动到B点.JS为DIV.style.left=B; 但是 ...
- Discuz封锁蜘蛛最有效的方法
闲来无事翻代码,发现一个好东西,Discuz设计者考虑到了有些流氓搜索引擎不遵守roborts.txt,于是设计了一个NOROBOT变量,当这个变量为true 的时候,定义中的搜索引擎都会无法访问,默 ...