1. 程式人生 > >javascript分析閉包和回撥函式

javascript分析閉包和回撥函式

<div id="box1">First Box</div>
<div id="box2">Second Box</div>
<script>
    function animateIt(elementId) {
      var elem = document.getElementById(elementId);
      var tick = 0;
      var timer = setInterval(function () {
        if (tick < 100) {
          elem.style.left = elem.style.top = tick + "px";
          tick++;
        } else {
          clearInterval(timer);
          if (tick === 100) {
            console.log("Tick accessed via a closure.");
          }
          if (elem) {
            console.log("Element also accessed via a closure.");
          }
          if (timer) {
            console.log("Timer reference also obtained via a closure.");
          }
        }
      }, 10);
    }
    animateIt("box1");
    animateIt("box2");
</script>

 

使用閉包來簡化單頁面中的多個物件動畫。

每次呼叫animateIt函式時,均會建立新的詞法環境1、2,該詞法環境儲存了動畫所需的重要變數(elementId、elem、動畫元素、tick、計數次數、timer、動畫計數器的ID)。只要至少一個通過閉包訪問這些變數的函式存在,這個環境就會一直保持。在本例中,瀏覽器會一直保持setInterval的回撥函式,直到呼叫clearInterval方法。隨後,當一個計時器到期,瀏覽器會呼叫對應的回撥函式,通過回撥函式的閉包訪問建立閉包時的變數。這樣就避免了手動匹配回撥函式的麻煩,啟用變數(3,4,5),極大的簡化了程式碼。

 

 

 

精通函式  閉包和作用域  小結

1.通過閉包可以訪問建立閉包時所處環境中的全部變數。閉包為函式建立時所處的作用域中函式和變數,建立“安全氣泡”。通過這種方式,即使建立函式時所處的作用域已經消失,

但是函式依然能夠獲得執行時所需要的全部內容。

 

2.我們可以使用閉包的這些高階功能:

2.1通過建構函式內的變數以及構造方法來模擬物件的私有屬性。

2.2處理回撥函式,簡化程式碼。

 

3.JavaScript引擎通過執行上下文棧(呼叫棧)跟蹤函式的執行。每次呼叫函式時,都會建立新的函式執行上下文,並推入呼叫棧的頂端。當函式執行完成後,對應的執行上下文將從

呼叫棧中退出。

 

4.JavaScript引擎通過詞法環境跟蹤識別符號(俗稱作用域)。

 

5.在JavaScript中,我們可以定義全域性級別、函式級別、塊級別的變數。

 

6.可以使用關鍵字var、let與const定義變數:

6.1關鍵字var定義距離最近的函式級變數或全域性變數。

6.2關鍵字let與const定義距離最近級別的變數,包括塊級變數。塊級變數在ES6之前版本的JavaScript中是無法實現的。此外,通過關鍵字const允許定義只能賦值一次的變數。

 

7.閉包是JavaScript作用域規則的副作用。當函式建立是所在的作用域消失後,仍能夠呼叫函式。

 

參考《JavaScript忍者祕籍》