日期:2014-05-16  浏览次数:20377 次

js 闭包之我的理解

一、js作用域:

??? 由于js没有像 java,c,c++等一样的用{}来定义一个变量的作用域,当然也不是说js就没有作用域的概念。

????? 我们看下面一段代码:

function f0(){
     var a = 0;
     b = 1;
}
function f1(){
     for(var i=0;i<5;i++){}
     alert(i);
}
?f0();
alert(a); //a is not defined
alert(b); //1
f1();//5

?可见,js中还是有作用域的,也就是全局变量和局部变量,只不过局部变量的访问是function内,而不是{}内。注:我们在函数内定义变量时用 var 则是局部变量,如果不用var 则是定义为全局变量,所以alert(b)时也就有值了。另,如果在函数内部定义的 var k,那么内部将不再使用全局变量k,如果如果在函数内部中在定义之前就使用了k的话是会报错的,同时可以使用window.k调用全局变量k。

、闭包

??? 由于定义了局部变量a,这样我们起到保护函数内的局部变量的作用但是有时候我们要在函数外部调用或者改变局部变量值时,则就需要用到闭包,请看下面一段代码。

function f0(){
     var a = 0;
     b = 1;
     function f1(){
       alert(++a)
    }
    return f1;
?}
?var c = f0();
c();//1
c();//2
var d=f0();
d();//1

?????? 在我们在执行var c = f0()就产生了一个闭包,也就是在函数外部调用内部变量时(定义的时候是没有的),就会产生闭包 ,这样函数内部定义的变量就不会在随着函数的结束而消失,而是一直存在了缓冲当中(由于js的缓存机制是在当没有调用时回收),所以,闭包要慎用,处理不当会造出浏览器内存溢出。

?

??????? 关于作用域和闭包我们来看一个经典的例子:

var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
		  alert(this.name);//My Object
      return function(){
			 alert(this.name);//The Window
      };
    }
  };
  object.getNameFunc()(); 

?上面的例子中object.getNameFunc()()等价于:

var f2=object.getNameFunc();//弹出My Object 在此getNameFunc为object的局?

????????????????????????????????????????????????????????????? //部函数

f2();//弹出 The Window 在此f2为全局函数

由于在外部调用了内部变量getNameFunc,而getNameFunc的存在依赖于object的存在,所以object将会一直存在。


三、匿名函数:

????? 所谓匿名函数就是没有名字的函数,一般匿名函数的调用有如下几种方式:

1、(function(){})();

2、(function(){}());

3、在定义触发的时候使用;

1/3是最常用的方式,之前我有一个误区,以为使用了匿名函数就不会产生闭包,这样js的GC就回将垃圾回收回去。GC是否回收回去,取决于函数外部是否调用了函数内部的参数。使用匿名函数的好处就是将局部变量封装,不那么依赖外部变量,当然,缺点也是那么的明显,由于是局部变量,没发引用,在firebug的dom中也看不到,如果使用了大量全局变量,那将是非常痛苦的事,不过在变成过程中还是推荐使用匿名函数。

?

??? 个人愚见,欢迎指正。