首先给个例子:

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定时执行任务

    (1)Linux下如何定时执行php脚本?(2)Linux下如何设置定时任务?(3)Crontab定时执行程序 核心提示:键入 crontab -e 编辑crontab服务文件 分为两种情况:(还有一 ...

  2. [问题2014A07] 复旦高等代数 I(14级)每周一题(第九教学周)

    [问题2014A07]  设 \(A\) 是有理数域 \(\mathbb{Q}\) 上的 4 阶方阵, \(\alpha_1,\alpha_2,\alpha_3,\alpha_4\) 是 \(\mat ...

  3. mongodb中的副本集搭建实践

    准备运行1个主节点,2个从节点,从节点中其中是一个是仲裁节点(Arb). --oplogSize --oplogSize --oplogSize 其中application是副本集的名称,节点必须相同 ...

  4. ubuntu14.04 64bit安装teamviewer

    1.下载teamviewer,链接如下: http://downloadus2.teamviewer.com/download/version_10x/teamviewer_10.0.36281_i3 ...

  5. (三)kafka集群扩容后的topic分区迁移

    kafka集群扩容后的topic分区迁移 kafka集群扩容后,新的broker上面不会数据进入这些节点,也就是说,这些节点是空闲的:它只有在创建新的topic时才会参与工作.除非将已有的partit ...

  6. 笔记本_thinkpad_e440

    ZC: 这是我现在手上 公司工作的笔记本 1.进入 BIOS --> Enter键 2.背面信息 笔记本序列号(用于查找 驱动等) (ZC: 这个是 ThinkPad E440 的信息) 序号为 ...

  7. 20160928_CentOS6.4x64_Oracle11gR2x64

    1.“Oracle Database 11g Release 2” 下载地址: http://www.oracle.com/technetwork/database/enterprise-editio ...

  8. ASP.NET 配置KindEditor文本编辑器

    ASP.NET 配置KindEditor文本编辑器 跟着这篇博客做了两个小时,只搞出了下面这么个东西. 时间浪费在了原博客里这样的一句话:将kindeditor/asp.net/bin/LitJSON ...

  9. Django1.9开发博客(11)- 富文本与代码高亮

    TinyMCE是一个轻量级的基于浏览器的所见即所得编辑器,支持目前流行的各种浏览器,由JavaScript写成. 功能配置灵活简单(两行代码就可以将编辑器嵌入网页中),支持AJAX.另一特点是加载速度 ...

  10. 亚马逊云服务器AWS安装CentOS

    亚马逊云服务器默认创建的实例,在停止之后再启动的情况下,IP会发生改变.所以我们最好先创建一个弹性IP,即EIP,不过我也不清楚这个费用. 1.按如图操作创建一个弹性IP,弹性IP创建之后可以随便绑定 ...