<strike id="3tkic"><sup id="3tkic"></sup></strike>

  1. <ul id="3tkic"></ul>
      <b id="3tkic"><legend id="3tkic"></legend></b>
      <b id="3tkic"><meter id="3tkic"></meter></b>

    • <strike id="3tkic"></strike>

      <blockquote id="3tkic"></blockquote>

    • 亚洲AV无码国产在丝袜线观看_亚洲第一页A∨在线_亚洲国产人成在线观看69网站_无码日韩人妻AV一区免费l

      Javacript的閉包是指什么

      2020/11/13 11:56:05   閱讀:2562    發(fā)布者:2562

      • 閉包:


      1.作為一個(gè)函數(shù)變量的一個(gè)引用,當(dāng)函數(shù)返回時(shí),其處于激活狀態(tài)。

      2.一個(gè)閉包就是當(dāng)一個(gè)函數(shù)返回時(shí),一個(gè)沒有釋放資源的棧區(qū)。


      簡單的說,javascript允許使用內(nèi)部函數(shù)---即函數(shù)定義和函數(shù)表達(dá)式位于另一個(gè)函數(shù)的函數(shù)體內(nèi)。而且,這些內(nèi)部函數(shù)可以訪問它們所在的外部函數(shù)中聲明的所有局部變量、參數(shù)和聲明的其他內(nèi)部函數(shù)。當(dāng)其中一個(gè)這樣的內(nèi)部函數(shù)在包含它們的外部函數(shù)之外被調(diào)用時(shí),就會形成閉包。



      • 變量的作用域


      要理解閉包,首先必須理解Javascript特殊的變量作用域。

      變量的作用域無非就是兩種:全局變量和局部變量。

      Javascript語言的特殊之處,就在于函數(shù)內(nèi)部可以直接讀取全局變量。

      js code:

      var n = 999;

      function f1(){

      console.log(n);

      }

      f1();  //999

      另一方面,在函數(shù)外部自然無法讀取函數(shù)內(nèi)的局部變量。

      js code:

      function f1(){

      var n = 999;

      }

      console.log(n);  //error

      這里有一個(gè)地方需要注意,函數(shù)內(nèi)部聲明變量的時(shí)候,一定要使用var命令。如果不用的話,你實(shí)際上聲明了一個(gè)全局變量。

      js code

      function f1(){

      n = 999;

      }

      f1();

      console.log(n);  //999

      • 如何從外部讀取局部變量?


      出于種種原因,我們有時(shí)候需要得到函數(shù)內(nèi)的局部變量。但是,前面已經(jīng)說過了,正常情況下,這是辦不到的,只有通過變通方法才能實(shí)現(xiàn)。

      那就是在函數(shù)的內(nèi)部,再定義一個(gè)函數(shù)。

      js code

      function f1(){

      n = 999;

      function f2(){

      console.log(n);  //999

      }

      }

      在上面的代碼中,函數(shù)f2就被包括在函數(shù)f1內(nèi)部,這時(shí)f1內(nèi)部的所有局部變量,對f2都是可見的。但是反過來就不行,f2內(nèi)部的局部變量對f1就是不可見的。這就是javascript語言特有的‘鏈?zhǔn)阶饔糜颉Y(jié)構(gòu)(chain scope),子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立。

      既然f2可以讀取f1中的局部變量,那么只要把f2作為返回值,我們就可以在f1外部讀取它的內(nèi)部變量了。

      js code

      function f1(){

      n = 999;

      function f2(){

      console.log(n);

      }

      return f2;

      }

      var result = f1();  //返回的是f2函數(shù)

      result();  //999

      • 閉包的概念


      上一節(jié)代碼中的f2函數(shù),就是閉包。

      閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),函數(shù)沒有被釋放,整條作用域鏈上的局部變量都將得到保留。

      由于在javascript語言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡單理解成‘定義在一個(gè)函數(shù)內(nèi)部的函數(shù)’。

      所以,在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接的一座橋梁。

      • 閉包的用途


      閉包可以用在許多地方。它的最大用處有兩個(gè),一個(gè)是前面提到的可以讀取函數(shù)內(nèi)部的變量,另一個(gè)就是讓這些變量的值始終保持在內(nèi)存中。

      js code

      function f1(){

      var n = 999;

      nAdd = function(){

      n += 1;

      }

      function f2(){

      console.log(n);

      }

      return f2;

      }

      var result = f1();

      result();  //從函數(shù)外部通過閉包f2獲取到函數(shù)f1內(nèi)部局部變量的值

      nAdd();  //從函數(shù)外部通過閉包修改局部變量n的值

      result();  //再次通過閉包f2獲取到函數(shù)f1內(nèi)部局部變量的值

      在這段代碼中,result實(shí)際上就是閉包f2函數(shù)。它一共運(yùn)行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數(shù)f1中的局部變量n 一直保存在內(nèi)存中,并沒有在f1調(diào)用后被自動清除。

      為什么會這樣呢?原因就在于f1是f2的父函數(shù),而f2被賦給了一個(gè)全局變量,這導(dǎo)致f2始終在內(nèi)存中,不會再調(diào)用結(jié)束后,被垃圾回收機(jī)制(garbage collection)回收。

      這段代碼中另一個(gè)值得注意的地方,就是‘nAdd=function(){n+=1}’這一行,首先在nAdd前面沒有使用var關(guān)鍵字,因此nAdd是一個(gè)全局變量,而不是局部變量。其次,nAdd的值是一個(gè)匿名函數(shù)(anonymous function),而這個(gè)匿名函數(shù)本身也是一個(gè)閉包,所以nAdd相當(dāng)于是一個(gè)setter,可以在函數(shù)外部對函數(shù)內(nèi)部的局部變量進(jìn)行操作。

      • 使用閉包的注意點(diǎn)


      1>由于閉包會使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會造成網(wǎng)頁的性能問題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法時(shí),在退出函數(shù)之前,將不使用的局部變量全部刪除。

      2>閉包會在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對象(object)使用,把閉包當(dāng)作它的公用方法,把內(nèi)部變量當(dāng)作它的私有屬性,這時(shí)一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。
      亚洲AV无码国产在丝袜线观看_亚洲第一页A∨在线_亚洲国产人成在线观看69网站_无码日韩人妻AV一区免费l
      <strike id="3tkic"><sup id="3tkic"></sup></strike>

      1. <ul id="3tkic"></ul>
          <b id="3tkic"><legend id="3tkic"></legend></b>
          <b id="3tkic"><meter id="3tkic"></meter></b>

        • <strike id="3tkic"></strike>

          <blockquote id="3tkic"></blockquote>

        • 巴彦淖尔市| 铜鼓县| 巨鹿县| 长丰县| 牡丹江市| 松江区| 来凤县| 兴和县| 绥化市| 洪湖市| 湘西| 辽宁省| 安徽省| 静海县| 海南省| 九江县| 娄烦县| 泽库县| 宁国市| 明光市| 阜宁县| 河间市| 盘山县| 平度市| 海宁市| 辽宁省| 梁河县| 巴青县| 舞阳县| 徐闻县| 平安县| 霍州市| 邢台县| 沛县| 平凉市| 繁峙县| 噶尔县| 上思县| 常熟市| 铜鼓县| 霍邱县|