1. 程式人生 > >關於JS閉包的理解

關於JS閉包的理解

一、概念的理解

  閉包(closure)是Javascript語言的一個難點,也是它的特色,很多高階應用都要依靠閉包實現。   這個概念看起來稍顯複雜,我之前也接觸過離散數學上閉包的概念,當時就不咋懂。(博主研究生專業研究的是偏數學的東西。。。)在JS紅寶書上是這樣定義的:“閉包是指有權訪問另一個函式作用域中的變數的函式。”   由於JS中變數的分為全域性變數和區域性變數,因此作用域也不同,在函式外部是無法讀取函式內的區域性變數。那麼閉包定義在函式內部,函式內部的變數相當於是它的全域性變數,自然可以訪問。例如:

function f1(){
    n=100;
    function f2(
){       alert(n);     }     return f2;   }   var result=f1();   result(); // 100

  程式碼中的f2函式就是一個閉包。結合一些部落格和資料,我的理解是,閉包就是能夠讀取其他函式內部變數的函式。本質上,閉包就是將函式內部和函式外部連線起來的一座橋樑。

二、閉包的用途

閉包的最大用途有兩個,一個是之前提到的可以讀取函式內部的變數,另一個就是讓這些變數的值始終保持在記憶體中。先看下面一段程式碼:

function f1() {
    var n = 99;
    Add = function() {
    		n +=
1     }     function f2() {       alert(n);     }     return f2;   }   var result = f1();   result(); // 99   Add();   result(); // 100

  在這段程式碼中,result即閉包f2函式。它一共運行了兩次,第一次的值是99,第二次的值是100。這說明函式f1中的區域性變數n一直儲存在記憶體中,並沒有在f1呼叫後被自動清除。   沒有被垃圾回收的原因就在於f1是f2的父函式,n對於f2是一個全域性變數,這導致f2始終在記憶體中,而f2的存在也依賴於f1,因此f1也始終在記憶體中,不會在呼叫結束後,被垃圾回收機制回收。   另外,不知道注意到沒有,就是“Add=function(){n+=1}”這一行,由於在Add前面沒有使用var關鍵字,使 Add是一個全域性變數,而不是區域性變數。並且Add的值是一個匿名函式,這個匿名函式本身也是一個閉包,所以Add可以在函式外部對函式內部的區域性變數進行操作。

本文只是簡單地介紹一下對閉包的理解,很多使用之處還需要多加註意和思考。學無止境,多多鑽研哈~