當一個函數的返回值是另一個函數,而返回的那個函數若是調用了其父函數內部的其它變量,若是返回的這個函數在外部被執行,就產生了閉包。閉包
使函數外部可以調用函數內部定義的變量。 函數
根據做用域鏈的規則,底層做用域沒有聲明的變量,會向上一級找,找到就返回,沒找到就一直找,直到window的變量,沒有就返回undefined。這裏明顯count 是函數內部的flag2 的那個count 。性能
var count=10; //全局做用域 標記爲flag1 function add(){ var count=0; //函數全局做用域 標記爲flag2 return function(){ count+=1; //函數的內部做用域 alert(count); } } var s = add() s();//輸出1 s();//輸出2
要理解閉包,首先必須理解Javascript特殊的變量做用域。 code
變量的做用域分類:全局變量和局部變量。 對象
特色: ip
一、函數內部能夠讀取函數外部的全局變量;在函數外部沒法讀取函數內的局部變量。 內存
二、函數內部聲明變量的時候,必定要使用var命令。若是不用的話,你實際上聲明瞭一個全局變量! 作用域
五、使用閉包的注意點 io
1)濫用閉包,會形成內存泄漏:因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁的性能問題,在IE中可能致使內存泄露。解決方法是,在退出函數以前,將不使用的局部變量所有刪除。 function
2)會改變父函數內部變量的值。因此,若是你把父函數看成對象(object)使用,把閉包看成它的公用方法(Public Method),把內部變量看成它的私有屬性(private value),這時必定要當心,不要隨便改變父函數內部變量的值。