我所理解的‘閉包’
一、什麽是閉包?
我相信有很多小夥伴和我一起,找了很多‘閉包’的字面解釋,當時看了之後,感覺記住了。但是過段時間又忘了‘閉包’是什麽了?所以現在你就只用記住一句話:“閉包允許函數訪問局部作用域之外的數據”。
現在我們來看一段閉包的代碼:
function makeName (){
let name = ‘zhangsan‘;
function displayName(){
alert(name);
}
return displayName;
}
fun();
此時運行瀏覽器它會顯示告警:
不對呀,按照我們對JavaScript“全局作用域”以及“局部作用域”的理解,全局環境怎麽能訪問到局部環境的“name”呢?沒錯,這就是JavaScript最強大特性之一的閉包了。
它允許我們訪問之前我們訪問不到的數據,那麽閉包是怎麽做到的呢?我們來看這樣一張圖:
在聲明函數時,JavaScript會為函數生成一個作用域鏈,這個作用域鏈是一個數組形式的,他會指向函數的局部對象和全局對象。函數運行完成時就會銷毀這個作用域鏈,但是如果我們把另一個函數displayName作為返回值並且持有makeName的name對象
那麽在makeName函數運行完成之後本來應該銷毀的局部對象name就不會被銷毀,name會存在於displayName函數的作用域中,所以當我們接受displayName函數之後並且試圖訪問name變量時,就會去displayName函數的作用域鏈中去找這個對象,那麽自然就找到了。不能被銷毀也就意味著腳本中閉包函數要比非閉包函數需要更多的內存開銷,所以我覺得如果不是必要,盡量不用閉包。但是閉包這個概念要理解。
本文參考了《高性能JavaScript》,如果本文有任何問題歡迎大家批評指正。 —— 一個熱愛代碼的小學生;
我所理解的‘閉包’