JS—闭包

作者: Miss____Du | 来源:发表于2014-12-12 00:22 被阅读242次
    • 闭包
      function createComparison(propertyName){
      return function(object1,object2){
      var value1=object1[propertyName];
      var value2=object2[propertyName];
      if(value1<value2){
      return -1;
      }else if(value1>value2){
      return 1;
      }else{
      return 0;
      }
      }
      }
      var object1={
      name:"dudu"
      }
      var object2={
      name:"lili"
      }
      var compare=createComparison("name");
      var result=compare(object1,object2);
      alert(result);//-1
      这个是书上给的例子:
      特点:
      • createComparison以匿名函数做返回值。
      • 匿名函数内部引用了外部函数的变量对象的形参变量propertyName
    • 闭包定义
      闭包是指有权访问另一个函数作用域中变量的函数
      就像上例,返回的匿名函数访问了外部函数作用域中的变量propertyName
    • 创建闭包的方式
      就是在一个函数的内部创建另一个函数。
    • 闭包涉及作用域链问题
      一般来讲,当函数执行完毕后,其内的局部活动对象以及相应的作用域链就会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象)。
      但是,闭包的情况又有所不同。
      外部函数在执行完毕后(成功返回匿名函数后),其执行环境的作用域链会被销毁,但他的活动对象仍然会留在内存中,因为匿名函数的作用域链仍然在引用这个活动对象,直到匿名函数被销毁后,外部函数的活动对象,因为没有被引用所以才会被销毁。
    • 销毁匿名函数
      如果返回的匿名函数没有继续被引用,那么他将被垃圾回收例程清除。
      所以由上文代码中这个匿名函数目前只被compare引用,只要不让这个已用类型继续引用这个匿名函数,那么这个匿名函数就不会有其他途径被其他变量引用了。
      //这时候,我们只需要
      compare=null;
    • 闭包涉及变量值变化问题
      作用域链对于闭包的这种配置机制,引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值。
      function createFunction(){
      var result=new Array();
      for(var i=0;i<10;i++){
      result[i]=function(){
      return i;
      };
      }
      return result;
      }
      result=createFunction();
      alert(result0);//10
      闭包在哪里?
      闭包在这里!
      result[i]=function(){
      return i;
      };
      为每一个数组对象定义一个匿名函数,每个匿名函数都是返回i的值,而这个i的值是引用自外部函数的变量i,每当执行这个函数数组内的每一个元素时,都会执行默认函数,且返回变量i的值,但是i的值依旧是10(i没有被销毁,因为js没有块级作用域)
      修改方法:
      result[i]=function(num){
      return function(){
      return num;
      }
      } (i);
      (i)这样的写法,是强制外部函数执行,i为传递的参数,传递一次参数其实就是一次函数的执行,就会为该函数创建一个执行环境以及作用域链。
      这样的修改方法,使得
      function(){ return num;}
      这个函数为闭包函数,他引用外部函数的变量num。
      缺点】这个方法虽然解决了闭包引用变量的问题,但是实在是太占用内存了,相当于一个函数内创建了10个闭包函数,那这10个闭包函数的外部函数所占用的资源(本例中的num)也不能释放。
    • 闭包涉及的this对象
      一般的,在全局函数中,this等于window,而当函数作为某个对象的方法时,this等于那个对象。
      不过闭包的执行环境具有全局性。因为内部函数在搜索this时,只会搜索其活动对象,然而闭包没有被其他对象调用,所以其this具有全局性
      var name="the window";
      var obj={
      name:"my window",
      getName:function(){
      return function(){
      return this.name;
      }
      }
      }
      alert(obj.getName()())//the window
      //等价于
      alert(this.name)
      【解决方法】
      1、把外部作用域中的this对象保存在一个闭包能够访问到的变量里。就可以让闭包访问这个对象了。
      var that=this;
      return function(){
      return that.name;
      }
      2、把闭包赋给这个对象。
      var name="the window";
      var obj={
      name:"my window",
      getName:function(){
      return function(){
      return this.name;
      }
      }
      }
      obj.getName=obj.getName();
      alert(obj.getName())//my window
    • 闭包的优缺点
      优点:

    相关文章

      网友评论

        本文标题:JS—闭包

        本文链接:https://www.haomeiwen.com/subject/nbmntttx.html