js 闭包和匿名函数

  1. 前面学了这么多知识,今天就来看看匿名函数和闭包吧!  
  2. 想要学习闭包先来看看什么是匿名函数吧!  
  3. (一)匿名函数  
  4.      匿名函数就是没有名字的函数。他有两种声明方式:  
  5.      1.典型的函数声明:  
  6.      function functionName(arg0,arg1,arg2){  
  7.          //函数体  
  8.      }  
  9.      2.函数表达式:  
  10.      var functionName = function(arg0,arg1,arg2){  
  11.          //函数体  
  12.      }  
  13. 虽然这两种方式在逻辑上市等价的,但是他们还是存在区别的。  
  14. 区别1:前者会在代码执行以前被加载到作用域中,而后者则是在代码执行到那一行的时候才会有意义。  
  15. 区别2:前者会给函数指定一个名字,而后者则是创建一个匿名函数,然后将这个匿名函数赋给一个变量。  
  16.        换句话说上面第二个例子:创建了一个带有3个参数的匿名函数,然后把这个匿名函数赋给了变量functionName,并没有给匿名函数指定名字。  
  17.   
  18. (二)闭包  
  19. 书上定义是这么说的:指有权访问另一个函数作用域中的变量的函数  
  20. 可是这种说法令新手难以理解。其实,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。  
  21.   
  22.      1.那我先来说说为什么要有闭包这么个概念吧,它产生的意义是什么呢?  
  23.      (1)首先我们学过前面的作用域了,知道了一个概念:函数内部可以直接读取全局变量。  
  24.      那么看代码:  
  25.      var n=999;  
  26.    function f1(){  
  27.     alert(n);  
  28.    }  
  29.    f1(); // 999  
  30.      (2)然后另外一个概念:在函数外部自然无法读取函数内的局部变量  
  31.       那么再看代码:  
  32.      function f1(){  
  33.     var n=999;  
  34.    }  
  35.    alert(n); //输出错误  
  36.      (3)这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!(我们以前也提到过的!)  
  37.      function f1(){  
  38.     n=999;  
  39.    }  
  40.    f1();  
  41.    alert(n); // 999  
  42.      下面关键的来了!:那就是如何从外部读取局部变量呢?  
  43.       那就是在函数的内部,再定义一个函数。(也就是闭包!!)  
  44.       function f1(){  
  45.         var n=999;  
  46.        function f2(){  
  47.           alert(n); // 999  
  48.        }  
  49.      }  
  50.      在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!来看代码:  
  51.      function f1(){  
  52.         var n=999;  
  53.        function f2(){  
  54.           alert(n);  
  55.        }  
  56.            return f2;  
  57.      }  
  58.        var result = f1();  
  59.        result(); //999  
  60. 这段代码与上面的不同点就是把f2函数作为了一个返回值,然后在调用它。这时你肯定在想最后两行什么意思啊?其实开始我也没闹明白,经过高人指点,其实这最后两行的意思就是要调用f2这个函数的返回值。这两行如果我改写一下是不是更容易明白了呢?  
  61.      var result = f1();  
  62.      result();  
  63.      合并成为:f1()();其实结果是一样的  
  64.      也可以更好的说明f2这个闭包的作用是:通过把它作为返回值(因为它能访问函数f1内的局部变量),然后从全局环境中调用这个返回值,这样自然就达到了我们的目的---从全局作用域中读取局部函数内的变量!  
  65.      2.既然知道了闭包的意义,下面就来了解下闭包的用途吧!  
  66.      (1)闭包的第一个用途,其实上面已经提到了,就是产生它意义:可以读取函数内部的变量  
  67.      (2)闭包的第二个用途,那就是:可以让这些变量的值始终保持在内存中  
  68.      第二个用途怎么理解呢?来看代码:  
  69.      function f1(){  
  70.          var n=999;  
  71.          nAdd=function(){  
  72.              n+=1  
  73.          }  
  74.          function f2(){  
  75.        alert(n);  
  76.      }  
  77.          return f2;  
  78.     }  
  79.      var result=f1();   //把f1函数的返回值(而这个返回值是函数f2的形式)给result  
  80.      result();          // 999   输出这个f2的返回值  
  81.      nAdd();            //调用nAdd函数  
  82.      result();          // 1000  这里就是闭包的第二个用途:f2这个闭包会让变量n的值始终保存在内存中  
  83. 光靠代码来理解第二种用途,好像没有什么说服力,下面就用画图的方法来让大家更深刻的理解!!  
  84.        
  85.   
  86. 第二种用途其实就和作用域链产生联系了,我来解释下:  
  87. 闭包f2从f1函数中被返回后,它的作用域链被初始化为包含f1函数的活动对象和全局变量对象(黑线部分)。这样f2就可以访问在f1()函数中定义的所有变量。更为重要的是就算f1()被执行完毕后,它的活动对象也不会被销毁,因为如图f2这个闭包还在引用f1函数的活动对象,这也就是为什么上述第二种用途的原因:闭包会让变量始终保存在内存中,直到闭包被摧毁。  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值