本文實例講述了JavaScript使用閉包模仿塊級作用域操作。分享給大家供大家參考,具體如下:
在閱讀這篇文章之前,建議先閱讀JavaScript的作用域鏈以及JavaScript閉包。
正如閉包的定義一樣:“閉包指的是有權訪問另一個函數作用域中的變量的函數”, 閉包最大的意義就在于閉包可以對另一個函數作用域的變量進行訪問,由此,閉包可以延伸出一系列的用法。
模仿塊級作用域
JavaScript沒有塊級作用域的概念。這意味著在塊語句中定義的變量,實際上是包含在函數中而非語句中創建的。從作用域鏈的角度來理解是,所有在函數內定義的變量(所有,也就是說塊語句中定義的變量也包含在內)都會在這個函數執行時所創建的函數的活動對象中,因此從函數內的所有變量定義開始,就可以在函數內部隨處訪問它,閉包也可以通過作用域鏈訪問它。
例子:
function outputNumbers(count){ for(var i = 0; i < count; i++){ console.log(i); // 0, 1, ... count - 1 } console.log(i); // count}C++, JAVA等語言中,變量i只會在for循環的語句塊(block)中有定義,循環一旦結束,變量i就會被銷毀。可是在JavaScript中,變量i是定義在outputNumbers()的活動對象中,因此從函數內的所有變量定義開始,就可以在函數內部隨處訪問它,閉包也可以通過作用域鏈訪問它。即使像下面這樣重新聲明同一個變量,也不會改變它的值。
function outputNumbers(count){ for(var i = 0; i < count; i++){ console.log(i); // 0, 1, ... count - 1 } var i; // redeclare i console.log(i); // count}JavaScript從來不管是否多次聲明了同一個變量;遇到這種情況,JavaScript只會對后續的聲明視而不見(不過會執行后續聲明中的變量初始化),將其當成一個賦值語句。
函數包裝器可以用來模仿塊作用域并避免這個問題。
函數包裝器就是創建并立即調用一個函數。
(function(){ console.log("Hello World!");})();這段代碼直接輸出”Hello World”, 這就是一個函數包裝器。
函數包裝器的作用:
1. 立即執行函數中的代碼,又不會再內存中留下對該函數的引用;
2. 函數內部的所有變量都會被立即銷毀(除非將這些變量賦值給了包含作用域中的變量)。
當在函數內部使用函數包裝器的時候,此時函數包裝器就是一個閉包,有權訪問外部環境中的所有變量。
function outputNumbers(count){ (function(){ //塊級作用域 for(var i = 0; i < count; i++){ console.log(i); // 0, 1, ... count - 1 } })(); console.log(i); // error}在函數包裝器中可以訪問外部環境outputNumbers()
新聞熱點
疑難解答
圖片精選