JavaScript高级编程学习3——闭包和匿名函数

 考虑下面的代码。

View Code
1 var firstVar = 'wuxq1';
2 function A() {
3 firstVar='wuxq2'
4 alert(firstVar);
5 return function () {
6 firstVar = 'wuxq3';
7 alert(firstVar);
8 }
9 }
10 var f = A();
11 f();

      当调用f()的时候会输出wuxq3,但是会有一个疑问,就是var f=A();之后A不是执行完毕,其执行环境会被销毁的。但是由于函数A的返回对象是一个匿名函数,也就是f包含着对A中匿名函数的引用。因此A中的匿名函数是不会被销毁的。而A执行完毕后,其执行环境和作用域链会被销毁,按理说其执行环境的变量也是会被销毁的!但是事实并不是如此,由于f对函数A的匿名函数存在着引用,因此A的匿名函数不会被销毁。而A的匿名函数的作用域链存在对A的变量对象的引用,因此A的变量对象不会被销毁。

      上面的代码其实就是运用了闭包。闭包就是能访问另一个函数作用域中变量的函数。而这个函数不一定非要是匿名函数。上面的代码还不能说明的很明显,看下面的另外一段代码。

View Code
1 function A() {
2 var privateVar;
3 function B() {
4 privateVar = 'wuxq';
5 return privateVar;
6 }
7 return B;
8 }
9 var funcB = A();
10 alert(funcB());

      由上面可知通过闭包我们可以访问函数作用域里面的变量。而且在funcB这个地方放引用资源没有被销毁之前,通过闭包访问的变量是会在内存中驻留的。这样性能上不是很好,当然也可以利用这个驻留,来实现我们的功能。如下面的代码,由于i在内存中一直驻留着,因此调用一次c() i会被加一次。

View Code
1 function a(){
2 var i=0;
3 function b(){
4 alert(++i);
5 }
6 return b;
7 }
8 var c = a();
9 c();

顺便点下ECMAScript的垃圾回收机制。如果一个对象没有再被引用那么这个对象会被GC回收,如果两个对象相互引用,这两个对象不再被第三方对象引用。则着两个对象会被回收。如果A引用B,A又被C引用,在C没有被销毁之前,A,B是都存在的。

参考文章:http://www.cnblogs.com/leoo2sk/archive/2010/12/19/ecmascript-scope.html

posted @ 2011-03-14 16:44  雁北飞  阅读(179)  评论(0编辑  收藏  举报