這次是一篇讀後感
深入理解javasrcipt原型與閉包-閉包
Javasrcipt秘密花園-函數之閉包與引用
#通讀兩篇關於閉包的文章之後,還是有點收穫的,就總結一下,怕自己忘記
#好,下面開始我的表演
閉包是什麼?
閉包是 JavaScript 一個非常重要的特性,這表示目前作用域總是能夠存取外部作用域中的變數。
(而在通常情況下目前作用域只能存取本身或上級的作用域),作用域這一部分下次再寫
函數是JavaScript 中唯一擁有自身作用域的結構,所以閉包的創建依賴函數。
閉包的時候,函數有兩種情況,
一種是函數作為傳回值
一種是函數作為參數傳遞
1。函數作為傳回值
function nihao(){var i=0;return function get(i){ i++; return i; } }var f=nihao(); f(1);
我們在控制台執行之後結果如下
執行結果為2
我們把get函數當作回傳值賦值給變數f,執行f(1)的時候,直接進入到get的作用域下,1賦值給i,執行完i++,i變成2,之後return i
2。函數作為參數傳遞
var a=2,b=function(c){ if(c>a){ console.log(c); } }; (function(f1){ var a=5; f1(3) })(b);
我們在控制台列印一下
##結果為3,可以看到,我們執行了一個匿名包裝器(自執行匿名函數),然後把函數b當作參數傳到了匿名函數裡面。 執行f1(3)其實就是在執行b=function(3)這裡有一個問題,我們在匿名包裝器內執行的時候,a已經重新定義為5,但是在執行到f1的時候,a又變為了2,所以3>2成立,執行了console.log根據執行結果,我是這麼理解的,當調用f1函數的時候,其實就是進入b=function()的作用域下了,而b又是用函數賦值表達式定義的函數所以,函數b和a其實是在同一個作用域下的,這個時候也會執行var a=2;等於是重新定義了一下a,所以當執行if(c>a)的時候,a就已經重新定義為2 以為已經結束了? 錯,我又去用函數宣告的方式測試了一下結果 是的,就算透過函數宣告的方式定義的b也是一樣結果為3所以這個和函數的定義方式無關,無論是函數宣告還是函數賦值表達式來定義,結果都是一樣的#那麼只能這麼理解了當我們執行f1(3)的時候,作用域就已經改變了,從匿名包裝器中的作用域轉移到了function b() 或者說var b=function()所在的作用域中了接著會執行if判斷,會尋找a,在函數b中沒找到,然後向父級中尋找,這裡定義了一個var a=2;這個時候a就找到了,然後繼續執行if語句3>2,接著執行console.log,輸出3總結了,兩個又好像沒有總結,完了,算了,先寫下一個把好,我們看在秘密花園中是這麼寫的
function Counter(start) { var count = start; return { increment: function() { count++; }, get: function() { return count; } } }var foo = Counter(4); foo.increment(); foo.get();看一下執行結果 我們來分析一下,這個什麼鬼的執行順序,首先透過函數賦值表達式的方式把Counter方法賦值給變數foo,那麼foo現在也是一個函數了
因為JavaScript 中不可以對作用域進行引用或賦值,因此沒有辦法在外部存取 count 變數。 唯一的途徑就是透過閉包。
以上是關於JavaScript閉包的小結的詳細內容。更多資訊請關注PHP中文網其他相關文章!