【JS进阶3】闭包和匿名函数

想要学习闭包先来看看什么是匿名函数吧!  
(一)匿名函数  
     匿名函数就是没有名字的函数。他有两种声明方式:  
     1.典型的函数声明:  
     function functionName(arg0,arg1,arg2){  
         //函数体  
     }  
     2.函数表达式:  
     var functionName = function(arg0,arg1,arg2){  
         //函数体  
     }  
虽然这两种方式在逻辑上市等价的,但是他们还是存在区别的。  
区别1:前者会在代码执行以前被加载到作用域中,而后者则是在代码执行到那一行的时候才会有意义。  
区别2:前者会给函数指定一个名字,而后者则是创建一个匿名函数,然后将这个匿名函数赋给一个变量。  
       换句话说上面第二个例子:创建了一个带有3个参数的匿名函数,然后把这个匿名函数赋给了变量functionName,并没有给匿名函数指定名字。
 
(二)闭包  
书上定义是这么说的:指有权访问另一个函数作用域中的变量的函数  
可是这种说法令新手难以理解。其实,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。  
  
     1.那我先来说说为什么要有闭包这么个概念吧,它产生的意义是什么呢?  
     (1)首先我们学过前面的作用域了,知道了一个概念:函数内部可以直接读取全局变量。  
     那么看代码:  
     var n=999;  
   function f1(){  
    alert(n);  
   }  
   f1(); // 999  
     (2)然后另外一个概念:在函数外部自然无法读取函数内的局部变量  
      那么再看代码:  
     function f1(){  
    var n=999;  
   }  
   alert(n); //输出错误  
     (3)这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!(我们以前也提到过的!)  
     function f1(){  
    n=999;  
   }  
   f1();  
   alert(n); // 999  
     下面关键的来了!:那就是如何从外部读取局部变量呢?  
      那就是在函数的内部,再定义一个函数。(也就是闭包!!)  
      function f1(){  
        var n=999;  
       function f2(){  
          alert(n); // 999  
       }  
     }  
     在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!来看代码:  
     function f1(){  
        var n=999;  
       function f2(){  
          alert(n);  
       }  
           return f2;  
     }  
       var result = f1();  
       result(); //999  
这段代码与上面的不同点就是把f2函数作为了一个返回值,然后在调用它。这时你肯定在想最后两行什么意思啊?其实开始我也没闹明白,经过高人指点,其实这最后两行的意思就是要调用f2这个函数的返回值。这两行如果我改写一下是不是更容易明白了呢?  
     var result = f1();  
     result();  
     合并成为:f1()();其实结果是一样的  
     也可以更好的说明f2这个闭包的作用是:通过把它作为返回值(因为它能访问函数f1内的局部变量),然后从全局环境中调用这个返回值,这样自然就达到了我们的目的---从全局作用域中读取局部函数内的变量!  
     2.既然知道了闭包的意义,下面就来了解下闭包的用途吧!  
     (1)闭包的第一个用途,其实上面已经提到了,就是产生它意义:可以读取函数内部的变量  
     (2)闭包的第二个用途,那就是:可以让这些变量的值始终保持在内存中  
     第二个用途怎么理解呢?来看代码:  
     function f1(){  
         var n=999;  
         nAdd=function(){  
             n+=1  
         }  
         function f2(){  
       alert(n);  
     }  
         return f2;  
    }  
     var result=f1();   //把f1函数的返回值(而这个返回值是函数f2的形式)给result  
     result();          // 999   输出这个f2的返回值  
     nAdd();            //调用nAdd函数  
     result();          // 1000  这里就是闭包的第二个用途:f2这个闭包会让变量n的值始终保存在内存中  
光靠代码来理解第二种用途,好像没有什么说服力,下面就用画图的方法来让大家更深刻的理解!!  
       
  
第二种用途其实就和作用域链产生联系了,我来解释下:  
闭包f2从f1函数中被返回后,它的作用域链被初始化为包含f1函数的活动对象和全局变量对象(黑线部分)。这样f2就可以访问在f1()函数中定义的所有变量。更为重要的是就算f1()被执行完毕后,它的活动对象也不会被销毁,因为如图f2这个闭包还在引用f1函数的活动对象,这也就是为什么上述第二种用途的原因:闭包会让变量始终保存在内存中,直到闭包被摧毁。
时间: 2024-08-06 19:28:44

【JS进阶3】闭包和匿名函数的相关文章

php闭包与匿名函数

不知不觉发现PHP已经出到了5.5版本,而自己一直在用PHP5.2,让我看起来像深山出来的小伙子一样,又土又落后.在我习惯在javascript中使用闭包之后,忽然间对PHP的闭包打起了兴趣. 于是乎在网上下了个WAMP集成开发环境,是PHP5.3版本的(PHP5.3开始引入了闭包的特性),不得不说WAMP安装使用真的很方便.简单配置了一下,开始动手. 匿名函数 提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它.声明一个匿名函数是这样: 1 $fun

PHP中的闭包和匿名函数

PHP中的闭包和匿名函数 闭包是指在创建时封装周围状态的函数.即使闭包所在的环境不存在了,闭包中封装的状态依然存在. 匿名函数就是没有名称的函数.匿名函数可以赋值给变量,还能像其他任何PHP对象那样传递.不过匿名函数仍是函数,因此可以调用,还可以传入参数.匿名函数特别适合作为函数或方法的回调. 注意:理论上讲,闭包和匿名函数是不同的概念.不过,PHP将其视作相同的概念.所以,我们提到闭包时,指的也是匿名函数,反之亦然. PHP闭包和匿名函数使用的句法与普通函数相同,但闭包和匿名函数其实是伪装成函

浅析PHP中的闭包和匿名函数

PHP闭包和匿名函数使用的句法与普通函数相同,但闭包和匿名函数其实是伪装成函数的对象(Closure类的实例) .下面给大家介绍PHP中的闭包和匿名函数知识,需要的朋友参考下吧 闭包是指在创建时封装周围状态的函数.即使闭包所在的环境不存在了,闭包中封装的状态依然存在. 匿名函数就是没有名称的函数.匿名函数可以赋值给变量,还能像其他任何PHP对象那样传递.不过匿名函数仍是函数,因此可以调用,还可以传入参数.匿名函数特别适合作为函数或方法的回调. 注意:理论上讲,闭包和匿名函数是不同的概念.不过,P

关于js的闭包和匿名函数

关于js闭包.之前我一直以为是匿名函数,以为封闭式的创建即执行销毁就是闭包,其实这是匿名函数,不一样的.也没有闭包的使用经验. 后来去网上查了下才知道,闭包的意思是:函数内部还有函数,返回一个函数,内部函数可访问外部函数的变量. 一个最简单的案例: a是外部函数,b是内部函数,b可以使用a的变量i,调用a函数返回b函数,执行c既是执行b.其实也就意味着在a函数的外部,读取到了a函数内部的变量值. a中的变量i将一直在内存中,直至c变量删除. 删除变量:delete c; { let a=func

js闭包,匿名函数概念

var functionName = function(arg){ //函数体 }; 匿名函数:创建一个函数,并将它赋值给一个变量,这种情况下创建的函数叫做匿名函数,因为function关键字后面没有标识符.(匿名函数有时候也叫拉姆达函数).匿名函数的name属性是空字符串. 注:FireFox.Safari.Chrome和Opera都给函数定义了一个非标准的name属性,通过这个属性可以访问给函数指定的名字.这个属性的值永远等于跟在function关键字后面的标识符. 闭包是指有权访问另一个函

JavaScript中的闭包与匿名函数

知识内容: 1.预备知识 - 函数表达式 2.匿名函数 3.闭包 一.函数表达式 1.定义函数的两种方式 函数声明: 1 function func(arg0, arg1, arg2){ 2 // 函数体 3 } 函数表达式: 1 var func = function (arg0, arg1, arg2){ 2 // 函数体 3 } 2.注意事项 函数表达式使用前必须赋值!像下面的代码是错误的: 1 say() 2 var say = function(){ 3 console.log("12

JS常用的三种匿名函数

第一种: var f1=function(p1,p2){ return p1+p2; };//将函数赋值给一个变量 alert(f1(1,3)); 匿名函数没法调用,只能赋值给一个变量,由于是赋值语句,后面要加分号 应用: ///document.getElementById(‘btn’).onclick=function(){} 第二种(*): (function(p1,p2){alert(p1+p2);})(20,30); 直接声明一个匿名函数,立即使用.用匿名函数省得定义一个用一次就不用的

闭包和匿名函数

在高级程序设计里,描述闭包是指有权访问另一个函数作用域中的变量的函数. 而经常创建方式是一个函数里包含另一函数. 而匿名函数就如"匿名"这两个意思一样. 所以匿名函数和闭包不是同一个概念. 在高级程序设计里描述匿名函数的执行环境具有全局性,所以this指向为window.这就是 为什么有时候发现this指向,不是自己所想的对象的问题. <!DOCTYPE html> <html lang="en"> <head> <meta

关于js中立即执行的匿名函数写法

1 /*最流行的写法*/ 2 (function() { 3 alert("run!") 4 })(); 5 6 /* !号可以有1~正无穷个,所以这一种就可以衍生无数种方式 */ 7 !!!(function() { 8 alert("run!") 9 })(); 10 11 (function() { 12 alert("run!") 13 }).call(); 14 15 (function() { 16 alert("run!&