2020/01/27, JavaScript

 官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。闭包的特点:

    1.作为一个函数变量的一个引用,当函数返回时,其处于激活状态。

    2.一个闭包就是当一个函数返回时,一个没有释放资源的栈区。

    简单的说,javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

  function closure(){
        var str = "I'm a part variable.";
        return function(){
            alert(str);
        } 
    }
    var fObj = closure();
    fObj();

 在上面代码中,str是定义在函数closure中局部变量,若str在closure函数调用完成以后不能再被访问,则在函数执行完成后str将被释放。但是由于函数closure返回了一个内部函数,且这个返回的函数引用了str变量,导致了str可能会在closure函数执行完成以后还会被引用,所以str所占用的资源不会被回收。这样closure就形成了一个闭包。

事实上,当我们给自定义的javascript类中的私有变量添加get/set函数时,已经用到了闭包。 

  function Class1(){
       var vari;
       this.getVari = function(){return vari;}
       this.setVari = function(_vari){vari = _vari;}
   } 
   var cls = new Class1();
   cls.setVari("test variable");
   alert(cls.getVari());

 

 在这个例子中,构造器中定义了变量vari,构造器执行结束后如果vari没有被其他外部能够应用的成员方法所引用时,这个变量将被回收。但是我们给它定义了get/set函数以后,由于这两个内部函数可以被包含他们的函数Class1(类)的外部所访问,且变量vari被这两个函数所引用,因此vari不会被回收。这样就形成了闭包。

 

Javascript垃圾回收的原则是:如果一个对象不再被引用,那么这个对象会被垃圾回收器回收。如果两个对象无干扰的互相引用,那么这两个对象也会被回收。

 闭包在javascript编程中有重要的作用,如果使用恰当,可以为某些问题的解决带来很多方便。但是如果使用不恰当,也会带来很多麻烦。  

1.为执行的函数提供参数。

    setTimeout可以延迟执行某个函数,原型如下: setTimeout(code,millisec)。其中第一个参数为需要执行的函数或者代码,第二个参数是延迟的毫秒数。常见用法:

 function sayHello(){
        alert("hello world");
   }
   setTimeout(sayHello,1000);

 但是可能我们会需要一个通用一些的函数,而不仅仅是只会说“hello world”。我们写一个say()函数,给say传递一个需要说的内容的参数。但是在setTimeout中我们无法给需要延迟执行的函数传递参数。使用闭包,我们可以这样做:

  function say(words){
       return function(){
           alert(words)
       }
   }   
   setTimeout(say("hello word"),1000);
   setTimeout(say("I'm hungry,I'm need some food!"),2000);

 

评论列表