深入解析Javascript闭包
首先给个例子:
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闭包的更多相关文章
- Javascript闭包深入解析及实现方法
1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点:1. 作为一个函数变量的一个引用,当函数返回时 ...
- JavaScript闭包深入解析
for (var i=1; i<=5; i++) { setTimeout( function timer() { console.log( i ); }, i*1000 ); } --上面这段 ...
- JavaScript闭包(Closure)
JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...
- javascript闭包和作用域链
最近在学习前端知识,看到javascript闭包这里总是云里雾里.于是翻阅了好多资料记录下来本人对闭包的理解. 首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法: 外部函数 ...
- Javascript闭包的一些研究
原文:Javascript闭包的一些研究 本文不谈闭包的概念,因为概念容易把人搞晕,本文希望通过几个鲜活的例子来探究闭包的性质,相信对理解闭包会有所帮助. 程序1 var f = (function( ...
- javascript闭包学习
(function(){})()===>>>>函数会被立即执行function(){}是一个函数用括号包起来表示是函数表达式再加()表示函数自执行 如何理解闭包?1.定义和用 ...
- javascript闭包—围观大神如何解释闭包
闭包的概念已经出来很长时间了,网上资源一大把,本着拿来主意的方法来看看. 这一篇文章 学习Javascript闭包(Closure) 是大神阮一峰的博文,作者循序渐进,讲的很透彻.下面一一剖析. 1. ...
- JavaScript闭包其一:闭包概论 函数式编程中一些基本定义
http://www.nowamagic.net/librarys/veda/detail/1707前面介绍了作用域链和变量对象,现在再讲闭包就容易理解了.闭包其实大家都已经谈烂了.尽管如此,这里还是 ...
- 【javascript闭包】转载一篇不错的解释,也有几个大牛的链接
初学闭包时一直以为很简单.但伴随对一个问题深入学习后,才算真正理解了闭包,同时也发现连<<JavaScript高级程序设计>>中都些不准确的地方. 我不准备从头介绍闭包的概念, ...
随机推荐
- python 学习笔记八 进程和线程 (进阶篇)
什么是线程(thread)? 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执 ...
- C#读取XML文件中有乱码的处理办法
1.以文本的方式读取出xml内容 2.如果xml加载文本失败,替换掉乱码的内容 private static void loadxml(XmlDocument doc, string str) { t ...
- DAL、DAO、ORM、Active Record辨析
转自:http://blog.csdn.net/suiye/article/details/7824943 模型 Model 模型是MVC中的概念,指的是读取数据和改变数据的操作(业务逻辑).一开始我 ...
- consul模板配置参数值示例
参看https://github.com/hashicorp/consul-template#examples // This is the address of the Consul agent. ...
- XML与JSON的转换
-(void)test { //XML文本范例 NSString *testXMLString = @"Cake0.55RegularChocolateBluebe ...
- 深入浅出设计模式——建造者模式(Builder Pattern)
模式动机无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮.方向盘.发送机等各种部件.而对于大多数用户而言,无须知道这些部件的装配细节,也几乎不会使用单 ...
- python的异常小结与assert
异常的处理 一. 二. -----------------2016-4-20 18:04:06--
- 手机号 和 email 的正则匹配
手机号 /^1[3|4|5|8] \d{9}$/ email /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/
- location.hash的摘抄
location.hash详解 去年9月,twitter改版. 一个显著变化,就是URL加入了"#!"符号.比如,改版前的用户主页网址为 http://twitter.com/us ...
- C++ const、volatile、mutable的用法 (转)
const.volatile.mutable的用法 鸣谢作者: http://blog.csdn.net/wuliming_sc/article/details/3717017 const修饰普通 ...