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