JavaScript中級筆記(4)

來源:互聯網
上載者:User
講解JavaScript中另一個重要的知識——閉包。
  

    5,閉包

  
    閉包意味著內層的函數可以引用存在於包圍它的函數內的變數,即使外層函數的執行已經終止。
    讓我們先來看一個閉包的例子。

<script type="text/javascript">
function add(num){
   return function(toAdd){
       return num+toAdd; //代碼①
   }
}

var addFive = add(5); //此時addFive為function(toAdd){return num+toAdd;}
var count = addFive(3); //此時count為 num+toAdd
alert(count);//8
</script>

    代碼①是處於函數內層,不過它可以使用外層的變數num。

    閉合還能解決另一個常見的Js問題,全域變數的影響。
    通過自動執行匿名函數組合閉包,便可把原本屬於全域的變數隱藏起來。看下面的例子:

<script type="text/javascript">
(function(){
   var msg = "Hello";
   window.onunload = function(){
       alert(msg);//輸出Hello
   }
})()

//alert(msg);//出現未定義
</script>

    在使用setTimeout時,我們經常也用上了閉包。

<html>
<head>
<title>demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
window.onload = function(){
   var obj = document.getElementById("abc");
   obj.style.border = "1px solid #000";
   setTimeout(function(){
       obj.style.color = "red";
   },1000)
  
   function DeAlert(msg , time){
       setTimeout( function(){
           alert(msg);
       },time)
   }
   DeAlert("hello",2000);
}
</script>
</head>
<body>
<div id="abc">CssRain</div>
</body>
</html>

    以這種方式使用setTimeout(),可以避免一些問題。

    當然使用閉包 也會帶來一些問題。如下代碼所示:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
window.onload = function(){
   var ul = document.getElementById("abc");
   var li = document.getElementsByTagName("li");
   for(var i=0;i<li.length;i++){
       li[i].onclick = function(){
           alert("你單擊的是第"+i+"個li。");
       }
   }
}
</script>
</head>
<body>
<ul id="abc">
   <li>AAA</li>
   <li>BBB</li>
   <li>CCC</li>
</ul>
</body>
</html>

    單擊li彈出的序號為 3 ,並不是正確的序號,它引用的值是最後一次的賦值。
    我們可以使用下面代碼來解決:

<script type="text/javascript">
window.onload = function(){
   var ul = document.getElementById("abc");
   var li = document.getElementsByTagName("li");
   for(var i=0;i<li.length;i++){
       (function(){ //使用一個自執行的匿名函數 來激發出範圍
           var b = i ;   //記住在這個範圍內的值
           li[b].onclick = function(){ //使用剛才記住的值,變數b
               alert("你單擊的是第"+b+"個li。");
           }
       })()
   }
}
</script>

    通過使用閉包對範圍的控制,從而符合了我們的要求。
    上面的代碼可以分解為:

<script type="text/javascript">
window.onload = function(){
   var ul = document.getElementById("abc");
   var li = document.getElementsByTagName("li");
   function a(){
           var b = 0 ;   
           li[b].onclick = function(){
               alert("你單擊的是第"+b+"個li。");
           }
   }
   function b(){
           var b = 1 ;
           li[b].onclick = function(){
               alert("你單擊的是第"+b+"個li。");
           }
   }
   function c(){
           var b = 2 ;  
           li[b].onclick = function(){
               alert("你單擊的是第"+b+"個li。");
           }
   }
   a();
   b();
   c();
}
</script>

   閉包的概念不容易掌握,我也是花了大量時間和精力才理解。

    6,小結
    筆記(2),(3),(4)講解了 JavaScript中的幾個重要的內容,包括引用,函數重載,範圍,內容物件和閉包。

    引用的關鍵內容:         指標,數組引用,字串引用,區別,傳值,傳址。
   函數重載的關鍵內容:    參數的數量,參數的類型,arguments,偽數組,typeof,constructor,區別-字串和對象。
   範圍的關鍵內容:       函數劃分,全域範圍,全域對象,window對象的屬性,局部範圍,顯式聲明,隱式聲明。
   內容物件的關鍵內容: this變數,call,apply,參數區別,數組。
   閉包的關鍵內容:         內層函數,外層函數,變數,setTimeout,閉包問題,最後一次的賦值,閉包和範圍。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.