JavaScript閉包詳解(一)

1.閉包定義

閉包就是能夠讀取其他函數內部變量的函數

應用的兩種情況——函數作爲返回值,函數作爲參數傳遞

第一,函數作爲返回值

如上代碼,bar函數作爲返回值,賦值給f1變量。執行f1(15)時,用到了fn作用域下的max變量的值。

第二,函數作爲參數被傳遞

如上代碼中,fn函數作爲一個參數被傳遞進入另一個函數,賦值給f參數。執行f(15)時,max變量的取值是10,而不是100。

要去創建這個函數的作用域取值,而不是“父作用域”

2.閉包示例:

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12

在這個示例中,我們定義了 makeAdder(x) 函數:帶有一個參數 x 並返回一個新的函數。返回的函數帶有一個參數 y,並返回 x 和 y 的和。

從本質上講,makeAdder 是一個函數工廠 — 創建將指定的值和它的參數求和的函數,在上面的示例中,我們使用函數工廠創建了兩個新函數 — 一個將其參數和 5 求和,另一個和 10 求和。

add5 和 add10 都是閉包。它們共享相同的函數定義,但是保存了不同的環境。在 add5 的環境中,x 爲 5。而在 add10 中,x 則爲 10。

3.內存泄漏

使用閉包的一個壞處是,在 IE 瀏覽器中它會很容易導致內存泄露。JavaScript 是一種具有垃圾回收機制的語言——對象在被創建的時候分配內存,然後當指向這個對象的引用計數爲零時,瀏覽器會回收內存
IE 瀏覽器有自己的一套垃圾回收機制,這套機制與 JavaScript 提供的垃圾回收機制進行交互時,可能會發生內存泄露。 在 IE 中,每當在一個 JavaScript 對象和一個本地對象之間形成循環引用時,就會發生內存泄露.

function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
        el.style.backgroundColor = 'red';
    }
}

這段代碼創建了一個元素,當它被點擊的時候變紅,但同時它也會發生內存泄露。爲什麼?因爲對 el 的引用不小心被放在一個匿名內部函數中。這就在 JavaScript 對象(這個內部函數)和本地對象之間(el)創建了一個循環引用

最簡單的一種是不要使用 el 變量

function addHandler(){
    document.getElementById('el').onclick = function(){
        this.style.backgroundColor = 'red';
    };
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章