通过示例学习JavaScript闭包

  

<强>译者按:在上一篇博客,我们通过实现一个计数器,了解了如何使用强闭包(关闭)* *,这篇博客将提供一些代码示例,帮助大家理解闭包。

  
      <李>   

    原文:JavaScript闭包假人

      李   <李>译者:Fundebug李   
  

<强>为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。

  

闭包并不神奇

  

其实,只要你领会了闭包的关键概念,一切就非常简单了。作为JavaScript开发者,你应该可以理解以下代码:

  示例1
  
 <=坝镅詊avascript代码类>函数sayHello(名字)
  {
  
  var='你好' +文本名称;
  
  var sayAlert=function () {console.log(文本);}
  
  sayAlert ();
  }
  
  sayHello (“Bob”)//输出“你好鲍勃” 
  

在<强> sayHello() 函数中定义并调用了<强> sayAlert() 函数;<强> sayAlert() 作为<强>内层函数强,可以访问<强>外层函数sayHello() 中的<强> 文本变量。理解这一点,你就可以继续阅读这篇博客了。

  

一个闭包示例

  

两句话总结闭包(注意,这个定义并不规范,但是有助于理解):

  
      <李>闭包就是函数的局部变量,这些变量在函数返回之后仍然可以访问李   <李>闭包就是函数的内存堆栈,这个内存堆栈在函数返回之后并没有被收回李   
  示例2
  
 <=坝镅詊avascript代码类>函数sayHello2(名字)
  {
  var='你好' +文本名称;//局部变量
  
  var sayAlert=function () {console.log(文本);}
  
  返回sayAlert;
  }
  
  var say2=sayHello2 (“Jane”);
  say2 ();//输出“Hello Jane” 
  

调用<强> sayHello2() 函数返回了<强> sayAlert 强,它是一个引用变量,指向一个函数。相信大多数JavaScript程序员能够理解什么是引用变量,而C程序员则可以把<强> sayAlert 以及<强> say2 理解为指向函数的指针。

  

C指针与JavaScript引用变量并无实质区分。在JavaScript中,不妨这样理解,指向函数的引用变量不仅指向函数本身,还隐含地指向了一个闭包。

  

代码中匿名函数<强>函数(){警报(文本);}是在另一个函数,即<强> sayHello2() 中定义的。在JavaScript中,如果你在函数中定义了一个函数,则创建了闭包。

  

对于C语言,以及其他绝大多数语言:函数返回之后,其局部变量将无法访问,因为内存中的堆栈会被销毁。

  

对于JavaScript,如果你在函数中定义函数的话,当外层函数返回之后,其局部变量仍然可以访问。代码中已经证明了这一点:当<强> sayHello2() 函数返回之后,我们调用了<强> say2() 函数,成功打印了<强> 文本变量,而<强> 文本变量正是<强> sayHello2() 函数的局部变量。

  

更多示例

  

如果只是从定义的角度去理解闭包,显然是非常困难。然而,如果通过代码示例去理解闭包,则简单很多,因此,强烈建议你认真地理解每一个示例,弄清楚它们是如何运行的,这样你会避免很多奇怪的错误。

  
示例3
  

<强>示例3 中,<强> say667() 函数返回后,<强> num 强变量将仍然保留在内存中,并且,<强> sayNumba 函数中的<强> num 强变量并非<强>复制强而是<强>引用强劲,因此它输出的是<强> 667 强而非<强> 666

  
 <=坝镅詊avascript代码类>函数say667 () {
  
  var num=666;//say667()函数返回后,num变量将仍然保留在内存中
  
  var sayAlert=function () {console.log (num);}
  
  num + +;
  
  返回sayAlert;
  
  }
  
  var sayNumba=say667 ();
  
  sayNumba ();//输出667  
  
示例4
  

<强>示例4 中,3个全局函数<强> gAlertNumber, gIncreaseNumber, gSetNumber 指向了同一个闭包,因为它们是在同一次<强> setupSomeGlobals() 强调用中声明的。它们所指向的闭包就是<强> setupSomeGlobals() 函数的局部变量,包括了<强> num 强变量。也就是说,它们操作的是同一个<强> num 强变量。

  
 <=坝镅詊avascript代码类>函数setupSomeGlobals () {
  
  var num=666;
  
  gAlertNumber=function () {console.log (num);}
  
  gIncreaseNumber=function () {num + +;}
  
  gSetNumber函数(x)={num=x;}
  
  }
  
  setupSomeGlobals ();
  gAlertNumber ();//输出666
  
  gIncreaseNumber ();
  gAlertNumber ();//输出667
  
  gSetNumber (5);
  gAlertNumber ();//输出5 

通过示例学习JavaScript闭包