close

  今天要來講一下JavaScript裡面很重要的一個觀念,閉包(Closure)。閉包是一個神奇的東西,簡單講就是當一個函式(無論是外部函式或內部函式)被宣告時,其可見範圍內的周圍所有變數與函式(通常指其父函式)都會被包起來變成一個防護泡,只要該函式還存在,該防護泡內的物件就會被保存下來,所以稱作閉包

  上圖就是一個閉包的概念,由上圖可知最後的outer()執行式因為實際上是指向Internal(),由於Internal在宣告時就已經建立了閉包,並且將其可視範圍的東西都包了進來,所以outer()仍能獨立運行Internal()所要做的事,並不受External()父函式已執行完被消滅的影響,這就是閉包的威力。

  這邊列舉一個最簡單的用閉包來封裝資訊的應用範例,模擬物件導向語言的私有變數只能透過物件所提供之方法來存取的實例,我們可以藉由閉包內提供的函式getNumber以及ChangeNumber來存取ObjectClass的變數privated_number,這是因為當JavaScript要建立物件時必須透過建構式,由於privated_number是宣告在建構式內,建構式又是一個函式,所以外界無法由外部存取,但是我們可以透過物件實體呼叫內部函式,而內部函式與變數同屬於一個閉包內,這樣就可以存取到私有變數啦。

ClosurePrivatedNum.html
   

<html>

  <head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <Title> 利用閉包封裝私有變數 </Title>

           <script>

             function ObjectClass() {

               var privated_number = 100;

               this.getNumber = function() { return privated_number;};

              this.changeNumber = function(x) {privated_number = x;};

             }

           </script>

  </head>

  <body>

    <ul>

             <script>

                     function changeObjNumber() {

                       var Obj = new ObjectClass();

                       var intext = document.getElementById("x1");

                       var outtext = document.getElementById("x2");

                       Obj.changeNumber(parseInt(intext.value));

                       outtext.value = Obj.getNumber();

                     }

             </script>

             <li>Input privated_number = <input id = "x1" type=”text” value="100" />&nbsp;&nbsp;&nbsp;&nbsp;<button type="button" onClick="changeObjNumber();">Change Value</button></li>

             <li>Results = <input id = "x2" type=”text” value="" /></li>

           </ul>

  </body>

</html>

   執行結果:

當你輸入完privated_number 按下 Change Value便可以改變Result

 

  閉包在JavaSctipt中被應用到的地方很廣,是掌握JavaScript的重要神器,不得不好好鑽研,這當然只是個開始,後面還有很長一段路要走的呢!

201759日星期二 1:13 AM

arrow
arrow
    創作者介紹
    創作者 jackterrylau 的頭像
    jackterrylau

    儒道哲學的浪漫人生

    jackterrylau 發表在 痞客邦 留言(0) 人氣()