1. 程式人生 > >js 閉包理解

js 閉包理解

我們先看一下維基百科對於閉包的解釋 這裡我們先只描述下閉包的概念 在PHP、JavaScript、Ruby、 Python、Go、Lua、objective c、swift 以及Java(Java8及以上)等語言中都能找到對閉包不同程度的支援。

可能看了這個官方的解釋會讓你感覺雲裡霧裡,我剛開始看的時候也很蒙,(這裡我要很感謝我的老大  每次不明白的地方都會和我講述清楚和背後的基礎原理)通過幾番戰鬥讓我對閉包有了一個新的認識。

下面我們通過js來描述下閉包的問題

我理解的閉包定義是:閉包就是當一個函式即使是在它的作用域之外被呼叫時,也可以記住並訪問它的作用域。

我們先看一段程式碼

可以看出函式 bar() 對於 foo() 內的作用域擁有訪問權,在這我們 return  bar 引用的函式物件本身。

在執行 foo() 之後,我們將它返回的值(我們的內部 bar() 函式)賦予一個稱為 baz 的變數,然後我們實際地呼叫 baz(),這將理所當然地呼叫我們內部的函式 bar(),只不過是通過把他複製給一個全域性變數物件的屬性baz

bar() 被執行了,在這個例子中,它是在它被宣告的作用域 外部 被執行的。

foo() 被執行之後,一般說來我們會期望 foo() 的整個內部作用域都將消失,因為我們知道 引擎 啟用了 垃圾回收器 在記憶體不再被使用時來回收它們。因為很顯然 foo()

 的內容不再被使用了,所以看起來它們很自然地應該被認為是 消失了

但是閉包的不會讓這發生。內部的作用域實際上 依然 在使用,因此將不會消失。誰在使用它啦? 函式bar()本身

有賴於它被宣告的位置,bar() 擁有一個作用域閉包覆蓋著 foo() 的內部作用域,閉包為了能使 bar() 在以後任意的時刻可以引用這個作用域而保持它的存在。

bar() 依然擁有對那個作用域的引用,而這個引用稱為閉包。閉包 使這個函式可以繼續訪問它定義的作用域

通過下面這個例子來說明 對那個作用域的引用,而這個引用稱為閉包的解釋

內部函式(timer)將它傳遞給 setTimeout()。但是 timer

 擁有覆蓋 wait(..) 的作用域的閉包,實際上保持並使用著對變數 message 的引用。

在我們執行 wait() 一秒之後,要不是內部函式 timer 依然擁有覆蓋著 wait() 內部作用域的閉包是不會打印出messgae的值

我們可以得到在直白一點的定義

有許可權訪問另一個函式作用域內變數的函式稱為閉包。

在閉包中因為變數被引用著所以不會立刻被垃圾回收,因此可以用來封裝私有變數。這即是閉包存在優點也是缺點,

閉包的好處:1.實現變數快取 2.實現封裝,防止變數跑到外層作用域中,發生命名衝突 3.匿名自執行函式,匿名自執行函式可以減小記憶體消耗

閉包的壞處:由於閉包會使得函式中的變數都被儲存在記憶體中,都會放在作用域鏈上面會加長作用域鏈 查詢就會變慢 會影響網站效能,使用不當很容易造成記憶體洩露

閉包是javascript語言的一大特點,主要是設計私有的方法和變數。jquery框架很能說明閉包的應用不想讓外部修改這些屬性可以設計一個閉包來只提供方法獲取

以上描述是個人對閉包的一些理解   歡迎大家指出問題和討論

下篇講述this與物件原型