Javascript閉包——詳解(記錄一下)

 當function裏嵌套function時,內部的function能夠訪問外部function裏的變量。數組

    function foo(x) {
        var tmp = 3;
        function bar(y) {
            alert(x + y + (++tmp));
        }
        bar(10);
    }
    foo(2)
閉包

  無論執行多少次,都會alert 16,由於bar能訪問foo的參數x,也能訪問foo的變量tmp。函數

  但,這還不是閉包。當你return的是內部function時,就是一個閉包。內部function會close-over外部function的變量直到內部function結束。spa

    function foo(x) {作用域

        var tmp = 3;
        return function (y) {
            alert(x + y + (++tmp));
        }
    }
    var bar = foo(2); // bar 如今是一個閉包
    bar(10);
io

  上面的腳本最終也會alert 16,由於雖然bar不直接處於foo的內部做用域,但bar仍是能訪問x和tmp。function

  可是,因爲tmp仍存在於bar閉包的內部,因此它仍是會自加1,並且你每次調用bar時它都會自加1.變量

  (考慮到六歲這個限制:咱們其實能夠創建不止一個閉包方法,好比return它們的數組,也能夠把它們設置爲全局變量。它們全都指向相同的x和相同的tmp,而不是各自有一份副本。)object

  注:如今來整點兒七歲的內容。引用

  上面的x是一個字面值(值傳遞),和JS裏其餘的字面值同樣,當調用foo時,實參x的值被複制了一份,複製的那一份做爲了foo的參數x。

  那麼問題來了,JS裏處理object時是用到引用傳遞的,那麼,你調用foo時傳遞一個object,foo函數return的閉包也會引用最初那個object!

    function foo(x) {
        var tmp = 3;
        return function (y) {
            alert(x + y + tmp);
            x.memb = x.memb ? x.memb + 1 : 1;
            alert(x.memb);
            }
        }
       var age = new Number(2);
       var bar = foo(age); // bar 如今是一個引用了age的閉包
       bar(10);

  不出咱們意料,每次運行bar(10),x.memb都會自加1。但須要注意的是x每次都指向同一個object變量——age,運行兩次bar(10)後,age.memb會變成2.

相關文章
相關標籤/搜索