Javascript杂谈 之 闭包

闭包(closureJavascript语言的一个必须要掌握难点,也是它的特色,很多高级应用都要依靠闭包实现

所谓闭包,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。闭包是一个表达式(一般是函数),它具有自由变量以及绑定这些变量的环境(该环境封闭了这个表达式)。(闭包,就是封闭了外部函数作用域中变量的内部函数。但是,如果外部函数不返回这个内部函数,闭包的特性无法显现。如果外部函数返回这个内部函数,那么返回的内部函数就成了名副其实的闭包。此时,闭包封闭的外部变量就是自由变量,而由于该自由变量存在,外部函数即便返回,其占用的内存也得不到释放。

上面的表述比较抽象,很难看懂,我对于“闭包”的简单理解是“闭包是定义在一个函数内部的函数,能够读取外部函数(非闭包函数)的变量,而内部变量不被外部函数读取,是函数内部和外部的一种沟通桥梁”。

下面用代码解释我的理解:

闭包中一定会涉及到“作用域”的问题,以后的博文将专门谈谈“作用域”。

先看一段代码:

 function f1(){
      var a= "HelloWorld";
      function f2(){
          return a;
      }
      function f3(){
          var b = "HelloKitty";
      }
      return b;
  }
  alert(a)//undefined
  alert(f1())//undefined
  alert( f1.f2())//HelloWorld

函数f1中嵌套着函数f2、f3,可以看出,函数f2可以获取到外部函数f1中的变量a,而f1不能访问f3中的变量b。

我们在外部,直接访问f1中的变量a,是访问不到的,通过访问f1.f2()。我们可以访问当变量a,这就是为什么说闭包可以作为函数内外的桥梁。

闭包的用处

闭包可以用在许多地方。它的最大用处有两个:①可以读取函数内部的变量;②让这些变量的值始终保持在内存中。

用处①上面的例子已经说明,我来说说②,请看下面的代码:

function f1(){
    var a = "Hello";
    f2 = function(){
        a += "World";
    }
    function f3(){
        return a;
    }
return f3; }
var f = f1(); f();//Hello f2(); f();//HelloWorld

 

 从上面代码可以看出,f执行了两次,结果却不一样,第一次是“Hello”,第二次是“HelloWorld”。这说明,变量a一直在内存中,并没用在f()执行后被回收。

在Javascript中,如果一个对象不再被引用,那么这个对象就会被垃圾回收机制(garbage collection)回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。而在上边例子中,f1是f3的父函数,而f3被赋给了一个全局变量,这导致f3始终在内存中,而f3的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后被回收。

使用闭包的注意点

1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

 

 

 

 

 

posted @ 2012-05-24 16:02  Just Game  阅读(129)  评论(0编辑  收藏  举报