Javascript 的函數式對象(二)從記憶體回收行程的角度理解閉包

來源:互聯網
上載者:User

function outerFunc(){

    var privateAttr = 10;

    return function(){
            privateAttr *= 2;
        return privateAttr;
    };
 
}

// 通過調用outerFunc函數,返回一個指向innerFunc函數的引用,
// 這個引用被賦給變數refInnerFunc
var refInnerFunc = outerFunc();
alert(refInnerFunc());

// 通過 refInnerFunc 這個引用調用到 innerFunc 函數
refInnerFunc(); // return 20 變數privateAttr可被innerFunc訪問並修改
refInnerFunc(); // return 40

// 調用outerFunc函數,建立了一個新的innerFunc函數的副本
var refInnerFunc2 = outerFunc();
refInnerFunc2(); // return 20 不同副本中變數privateAttr的值是獨立的。

 

 

 

當一個javascript函數返回時,js解析器會保留它範圍內的所有變數和函數。

 

閉包(Closure)這個詞形象地描述了函數範圍現場被“封閉包存”起來這一行為。

 

直到該函數不再被其他對象引用,其範圍內的變數和函數才能被釋放回收。 

 

按照java回收機制的解釋,方法內的局部變數在該方法被執行完畢後,

 

如果不再被其他對象引用,記憶體回收行程可自行選擇適當的時機回收這些局部變數。

 

但js的記憶體回收機制和java不同,上述js代碼的執行結果便可以證明這一點。

 

js的記憶體回收機制同樣是對不再被其他對象引用的變數或方法進行回收,

 

但因為js的引用不僅可指向變數,也可指向函數,在上述js代碼中,

 

只要指向函數 innerFunc 的引用 refInnerFunc 還沒有被設為null,

 

那麼處在函數 innerFunc 範圍內的局部變數都不會被js記憶體回收行程回收。

 

局部變數 privateAttr 被認為處在一個安全且相對封閉的“閉包”環境中,

 

訪問它的唯一方法是通過調用處在同一範圍下的 innerFunc 函數來進行。

 

 

直到 innerFunc 函數不再被其他對象引用,其範圍內的變數和函數才能被釋放回收。 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.