在面試中,怎樣能通俗易懂又不白痴的回答出面試官提出的js中閉包問題?

前端 互聯網 面試


閉包真的是javascript學習者繞不過去的一道坎,而且是面試初級甚至中級前端必問的一個面試點。

簡單總結下,要點就你自己提取吧。

1.首先明確閉包是函數而不是一個事物或者一個過程。明確了閉包是函數後,接下來就要搞清楚什麼樣的函數才能稱為閉包。

2. 函數執行的時候會先創建一個屬於該函數的上下文執行環境,這個上下文包含了作用域在內的相關信息。當一個函數執行完畢後,與該函數相關的上下文環境便會收回。

3.但是當閉包出現的時候,這個該被收回的環境就不會被收回了,因此也就產生了閉包。原因就是因為在這個函數執行的時候,它內部有對不屬於這個作用域並且也不屬於全局作用域的局部變數的引用。具體看下面的示例:

function outer() {

var a = 1;

function inner() {

console.log(a++);

}

return inner;

}

var retFun = outer();

retFun();//2

retFun();//3

retFun();//4

說明:outer函數嵌套inner函數,outer作用域內的變數a本應在outer執行完之後收回。但是因為outer執行完後返回了inner函數,而inner函數要想成功執行就必須依賴外部變數a。所以,為了不出現問題,此時在outer執行完畢後原本屬於outer的執行環境並沒有被收回。所以每次執行retFun(也就是內部函數inner)的時候引用的a都是一直存在的。

從上面的示例可以知道,閉包大多出現在嵌套函數內部。當被包裹的函數引用到了他的父級(如果嵌套層數深的話也可能是祖父級)作用域內的變數而且該被包裹函數被當做值return出去的時候,便形成了閉包。

為什麼呢?因為函數在執行的時候會創建與該函數有關的執行上下文環境,閉包執行時候的上下文環境很特殊,因為他有引用自身外部作用域的變數,牽扯到了外部函數執行環境。但是理論上來說,外部函數在執行完畢後就應該被收回執行環境,按照這個理論說法的話,這裡就會出現問題,因為內部函數執行的時候就會找不到外部變數。為了避免這個問題出現,所以javascript就將外部作用域的變數保存了下來,也就是外部作用域相關信息保存了下來。

所以上面的值一直遞增而不是始終不變,因為閉包每次執行都是在引用同一個變數而不是重新生成的,這個變數在閉包第一次執行的時候被保存了起來。

閉包明顯可以保存作用域外的變數值,這個特性可以加以利用,但是同時也存在了內存泄漏的風險,因為外部函數執行完後屬於該函數的上下文環境沒有被收回。


講的很好,易懂。學習了


用看傻逼的眼神看他,說這還用問?你在侮辱我


推薦閱讀:

不清楚到底是怎麼基於ES6模塊 進行模塊靜態分析的??
angularJS1.X學到一半發現2.0的存在,要不要繼續1.X?
如何看待 Immutable App Architecture?
asy?
如果將來想從事web前端開發,而我專業並不是學的這個,需要做哪些準備?

TAG:前端開發 | 面試 | 程序員面試 |