前段時間面試,問到最多的就是關於閉包問題,所以,今天想來總結一下閉包知識點,以便大家能在今后無論工作還是面試過程中,都能夠熟悉的運用
我的理解是,閉包就是能夠讀取其他函數內部變量的函數。
由於在Javascript語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解成"定義在一個函數內部的函數"。
所以,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋梁。
閉包的用途
閉包可以用在許多地方。它的最大用處有兩個,一個是前面提到的可以讀取函數內部的變量,另一個就是讓這些變量的值始終保持在內存中。
function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000
我們來看一下閉包應用的常見的場景
場景一 采用函數引用方式的setTimeout調用(這個曾在面試中遇到過,所以印象格外深刻)
閉包通常的用法是為一個在某一函數執行前先執行的函數提供參數,例如在web環境中,一個函數作為setTimeout函數調用的第一個參數,是一種常見的應用
原生的setTimeout有一個缺陷,就是傳遞的第一個參數不能夠代帶參數,即
setTimeout(func(parma),1000) // 這樣的語句是不能生效的
這時我們就可以用閉包來實現這個效果了
function func(param) {
return function() { alert(param); } } var f = func(1) setTimeout(f, 1000);
使用閉包的注意點
1)由於閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。
2)閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。