Javascript閉包(Closure)

1.Javascript特殊的變量做用域。
變量的做用域無非就是兩種:全局變量和局部變量。
Javascript語言的特殊之處,就在於函數內部能夠直接讀取全局變量。閉包

function f1() {
    var n = 999;
}
alert(n); // error沒有變量n

函數內部聲明變量的時候,必定要使用var命令。若是不用的話,你實際上聲明瞭一個全局變量!函數

function f2() {
    n = 999;
}
f2();
alert(n); // 999

2.Javascript語言特有的"鏈式做用域"結構(chain scope),性能

子對象會一級一級地向上尋找全部父對象的變量。
父對象的全部變量,對子對象都是可見的,反之則不成立。this

3.什麼是閉包:
當內部函數在定義它的做用域的外部被引用時,就建立了該內部函數的閉包spa

這個不是閉包code

function f3(x) {
    var temp = 3;
    function bar(y) {
        temp = temp + 1;
        alert(x + y + temp);
    }
    bar(10);
}
f3(2) //2+10+4=16; 無論執行多少次,都會alert 16,由於bar能訪問foo的參數x,也能訪問f3的變量tmp。這個不是閉包

閉包對象

function f4(x) {
    var temp = 3;
    return function (y) {
        temp = temp + 1;
        alert(x + y + temp);
    }
}
var bar = f4(2); // bar 如今是一個閉包
bar(10);//第一次16,第二次17,每次自動加1
f4(2)(10); //這個每次都是16,由於每次都是一個新的對象,這個對象是不存在的,與上面的區別是上面的已經存在。
function f5() {
    var n = 999;
    nAdd = function () { n += 1 } //nAdd前面沒有使用var關鍵字,所以nAdd是一個全局變量,而不是局部變量
    function f6() {
        alert(n);
    }
    return f6;
}
var result = f5();
result(); // 999
nAdd();   
result(); // 1000

var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function () {
        alert(this.name);  //My Object
        return function () {
            return this.name; //當前的name,沒有的話當成全局變量
        };
    }
};
alert(object.getNameFunc()()); //The Window

var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function () {
        var that = this;
        return function () {
            return that.name;
        };
    }
};
alert(object.getNameFunc()());//My Object

4.閉包的注意點:blog

1)因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁的性能問題,在IE中可能致使內存泄露。解決方法是,在退出函數以前,將不使用的局部變量所有刪除。
2)閉包會在父函數外部,改變父函數內部變量的值。因此,若是你把父函數看成對象(object)使用,把閉包看成它的公用方法(Public Method),把內部變量看成它的私有屬性(private value),這時必定要當心,不要隨便改變父函數內部變量的值。ip

相關文章
相關標籤/搜索