深入解析Javascript闭包

首先给个例子:

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

var test=PfnOuter();
test();        //999

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

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

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

var test=PfnOuter();
test();        //999
nAdd();
test();        //1000

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个变量对象均被释放。

时间: 2024-10-25 11:25:48

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

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

一.什么是闭包和闭包的几种写法和用法 1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点:1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态.2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区.简单的说,Javascript允许使用内部函数-即函数定义和函数表达式位于另一个函数的函数体内.而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数和声明的其他内部函

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

1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点:1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态.2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区.简单的说,Javascript允许使用内部函数—即函数定义和函数表达式位于另一个函数的函数体内.而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数和声明的其他内部函数.当其中一个这样的内部函数在包含它们

JavaScript ---- 闭包(什么是闭包,为什么使用闭包,闭包的作用)

经常被问到什么是闭包? 说实话闭包这个概念很难解释.JavaScript权威指南里有这么一段话:"JavaScript函数是将要执行的代码以及执行这些代码作用域构成的一个综合体.在计算机学术语里,这种代码和作用域额综合体叫做闭包.".言外之意所有的JavaScript函数都是闭包. 有人会说,这个解释不对.我们经常说的闭包应该像下面的一串代码: var f1 = function(){ var a=1; return function f2(){ a++; alert(a) } } v

Javascript闭包!

# javascript闭包(Closure) > 所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 上面是官方的解释,但这解释只会让人头晕.要理解闭包,首先理解两点:变量的作用域以及作用域链,这两个在前面都已经介绍过了,并且举了简单了列子,来回顾一下: var color = "blue";       function changeColor(){              var anotherColo

精华分享:深爱—— javascript 闭包

上次一篇简单的干货分享,只想让你分分钟学会javascript中的闭包,这就好比一辆车摆在你面前让你束手无策,我只想让你简单的学会驾驶它,仅此而已.而这次我们将从原理层面分析 javascript 引擎如何执行一段代码.一个函数,以及如何形成一个闭包,让你从“爱的初体验” 变得 “深爱” . 1 var a = 1; 2 3 function f1(b){ 4 var a = 2; 5 function f2(c){ 6 console.log(a+b+c); 7 } 8 return f2;

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

http://www.nowamagic.net/librarys/veda/detail/1707前面介绍了作用域链和变量对象,现在再讲闭包就容易理解了.闭包其实大家都已经谈烂了.尽管如此,这里还是要试着从理论角度来讨论下闭包,看看ECMAScript中的闭包内部究竟是如何工作的. 在直接讨论ECMAScript闭包之前,还是有必要来看一下函数式编程中一些基本定义. 众所周知,在函数式语言中(ECMAScript也支持这种风格),函数即是数据.就比方说,函数可以赋值给变量,可以当参数传递给其他

JavaScript教程之JavaScript 闭包

JavaScript 变量可以是局部变量或全局变量. 私有变量可以用到闭包. 全局变量 函数可以访问由函数内部定义的变量,如: 实例 function myFunction() {    var a = 4;    return a * a;} 尝试一下 ? 函数也可以访问函数外部定义的变量,如: 实例 var a = 4;function myFunction() {    return a * a;} 尝试一下 ? 后面一个实例中, a 是一个 全局 变量. 在web页面中全局变量属于 wi

Javascript闭包的一些研究

原文:Javascript闭包的一些研究 本文不谈闭包的概念,因为概念容易把人搞晕,本文希望通过几个鲜活的例子来探究闭包的性质,相信对理解闭包会有所帮助. 程序1 var f = (function() { var n = 10; return function() { ++n; console.log(n); } })(); f(); 输出: 11 结论: 闭包函数可以访问外层函数中的变量. 程序2 var arr = []; (function() { var n = 0; for (var

[Js]JavaScript闭包和范围的快速测试

1. if (!("a" in window)) { var a = 1; } alert(a); [分析]代码含义:如果window不包含属性a,就声明一个变量a并赋值为1 ①Js引擎会先扫描所有的变量声明 ②所有的全局变量都是window的属性 ③变量声明和赋值一起用时,Js引擎会自动将它分成两部分:变量声明提前,变量赋值没有(不将赋值提前是因为他有可能影响代码执行出不可预期的结果) 所以代码执行顺序等价于 var a; if(!("a" in window))