首先给个例子:

function PfnOuter(){
var num=999;
function PfnInner(){
alert(num);
}
return PfnInner;
} var test=PfnOuter();
test(); //

上述实例中PfnInner函数就是闭包,闭包简单的理解就是能够读取其它函数内部变量的函数。由于Javascript中只有函数内部的子函数才能读取函数内部的变量,因此闭包也可以简单的理解成定义在一个函数内部的函数,闭包就是将函数内部和函数外部链接起来的一座桥梁。

闭包有2大主要的作用:一是可以读取函数内部的变量,二是可以让这些变量一直保存在内存中。再举一个例子:

function PfnOut(){
var num=999;
nAdd(){
num++;
}
function PfnInner(){
alert(num);
}
return PfnInner;
} var test=PfnOuter();
test(); //
nAdd();
test(); //

test实际上就是闭包函数PfnInner,它一共运行了2次,第一次是999,第二次是1000;这个足以证明num一直存在内存中,并没有在PfnInner函数调用完成之后给释放,这就可以实现类似C++中的静态变量。

让我们对其中的原理进行深入的解析,PfnOuter是PfnInner的父函数,而PfnInner赋值给一个全局变量,这导致PfnInner一直在内存中,而PfnInner又依赖于PfnOuter,因此PfnOuter也一直在内存中,不会被回收。

还有一个值得注意的,在Javascript中如果声明局部变量,需要var关键之,否则认为该变量是一个全局变量,因此,上述代码中的nAdd就是一个全局的变量,nAdd的值是一个匿名函数,而这个匿名函数的本身就是一个闭包,所以nAdd可以在函数外部对函数的变量进行操作。

显然,使用闭包需要有几点注意的地方:
1.滥用闭包造成内存无法释放,在IE中很容易造成内存泄露,解决方法是在函数退出是将不使用的变量给全部删除,也就是将不需要的变量赋值为null;
2.闭包函数会在父函数外部修改父函数内部的变量,所以如果吧父函数当做对象使用,把闭包当做共有方法使用,把父函数内部的变量当做私有变量时一定要注意要随随便便调用闭包函数修改内部变量。

总结一下闭包:
当内部函数 在定义它的作用域的外部被引用时,就创建了该内部函数的闭包 ,如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被释放,因为闭包需要它们。

在以上谈到闭包的时候,提到了Javascript内存泄露,接下来简单讲述一下Javascript的内存释放,在Javascript中一个对象不比其他地方引用[比如将该对象赋值为null],垃圾回收期会回收该变量,如果2个对象相互引用,比如闭包的关系,若这2个变量不被其他地方引用,则这2个变量对象均被释放。

深入解析Javascript闭包的更多相关文章

  1. Javascript闭包深入解析及实现方法

    1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点:1. 作为一个函数变量的一个引用,当函数返回时 ...

  2. JavaScript闭包深入解析

    for (var i=1; i<=5; i++) { setTimeout( function timer() { console.log( i ); }, i*1000 ); } --上面这段 ...

  3. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

  4. javascript闭包和作用域链

    最近在学习前端知识,看到javascript闭包这里总是云里雾里.于是翻阅了好多资料记录下来本人对闭包的理解. 首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法: 外部函数 ...

  5. Javascript闭包的一些研究

    原文:Javascript闭包的一些研究 本文不谈闭包的概念,因为概念容易把人搞晕,本文希望通过几个鲜活的例子来探究闭包的性质,相信对理解闭包会有所帮助. 程序1 var f = (function( ...

  6. javascript闭包学习

    (function(){})()===>>>>函数会被立即执行function(){}是一个函数用括号包起来表示是函数表达式再加()表示函数自执行  如何理解闭包?1.定义和用 ...

  7. javascript闭包—围观大神如何解释闭包

    闭包的概念已经出来很长时间了,网上资源一大把,本着拿来主意的方法来看看. 这一篇文章 学习Javascript闭包(Closure) 是大神阮一峰的博文,作者循序渐进,讲的很透彻.下面一一剖析. 1. ...

  8. JavaScript闭包其一:闭包概论 函数式编程中一些基本定义

    http://www.nowamagic.net/librarys/veda/detail/1707前面介绍了作用域链和变量对象,现在再讲闭包就容易理解了.闭包其实大家都已经谈烂了.尽管如此,这里还是 ...

  9. 【javascript闭包】转载一篇不错的解释,也有几个大牛的链接

    初学闭包时一直以为很简单.但伴随对一个问题深入学习后,才算真正理解了闭包,同时也发现连<<JavaScript高级程序设计>>中都些不准确的地方. 我不准备从头介绍闭包的概念, ...

随机推荐

  1. Linux 各文件夹介绍

    http://www.cnblogs.com/amboyna/archive/2008/02/16/1070474.html linux下的文件结构,看看每个文件夹都是干吗用的/bin 二进制可执行命 ...

  2. hdu1242 优先队列+bfs

    Rescue Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  3. Linux - 进程查看与管理

    标签(空格分隔): Linux 进程的静态查看 查看系统所有进程 ps -ef -- 输出来好乱,看不懂..: ps aux -- a表示所有与终端相关的进程,u表示所有以用户组织的进程状态的信息,x ...

  4. SQL疑难杂症【4 】大量数据查询的时候避免子查询

    前几天发现系统变得很慢,在Profiler里面发现有的SQL执行了几十秒才返回结果,当时的SQL如下: 可以看得出来,在652行用了子查询,恰巧目标表(QS_WIP)中的记录数为100000000+, ...

  5. loadrunner录制脚本方式笔记

    1.脚本录制的基本原则 充分考虑脚本的执行效率 性能测试脚本关注的是如何模拟用户的真实行为.因此,用于测试的脚本应该接近用户的真正操作.这就要求录制后         的脚本在修改的过程中不要增加过多 ...

  6. hdu2896病毒侵袭(ac自动机)

    链接 ac自动机的模板题 说2个注意的地方 一是题目说明包含所有ASCII字符,可以开到0-127 包含空格 题目会输入多个源串,在加完当前的val值时,不应清0,可以开个标记数组. #include ...

  7. PHP 小方法之 二维数组排序

    if (! function_exists ( 'multi_array_sort' )) { function multi_array_sort($arr, $keys, $type = 'desc ...

  8. MAC air 安装redis-3.0.6

    redis版本: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px Menlo; color: #c33720; background-colo ...

  9. python—基础类的那点儿所以然

    老师说:‘要知其然,更要知其所以然’~~~那么今天就来说点儿所以然,对python中的int,str,lst,dict和tuple等基础类中的方法做一些解析 那么类是什么呢? 官方的解释是这样的:对象 ...

  10. C#中文和UNICODE编码转换

    C#中文和UNICODE编码转换 //中文轉為UNICODE string str = "中文"; string outStr = ""; if (!strin ...