03.07 「前端架構師30天快速掌握js17」之閉包知識點詳解

此篇文章講解目錄:

  • 閉包的由來

  • 閉包的概念

  • 閉包的用途

  • 使用閉包的注意點

閉包的由來

  1. 變量的作用域(全局變量和局部變量)

上一章中,我們知道,變量的作用域無非就分成兩種:全局變量、局部變量

函數內部可以讀取到全局變量

函數外部無法讀取函數內的局部變量

「前端架構師30天快速掌握js17」之閉包知識點詳解

  1. 如何在外部讀取局部變量

出於種種原因,我們有時候需要得到函數內的局部變量。但是,前面已經說過了,正常情況下,這是辦不到的,只有通過變通方法才能實現。

那就是在函數的內部,再定義一個函數。

「前端架構師30天快速掌握js17」之閉包知識點詳解

在testFunc1中,我們定義了一個testFunc2,在testFucn2中,操作了局部變量testScope,然後將testFunc2作為返回值,這樣,就可以在函數外,讀取到testFunc1中的局部變量了

閉包的概念

上面的代碼中,testFunc2就是一個閉包。

各種專業文獻上的"閉包"(closure)定義非常抽象,很難看懂。我的理解是,閉包就是能夠讀取其他函數內部變量的函數。

由於在Javascript語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解成"定義在一個函數內部的函數"。

所以,在本質上,閉包就是將函數內部和函數外部連接。

閉包的用途

  1. 匿名自執行函數

我們知道所有的變量,如果不加上var關鍵字,則默認的會添加到全局對象的屬性上去,這樣的臨時變量加入全局對象有很多壞處,比如:別的函數可能誤用這些變量;造成全局對象過於龐大,影響訪問速度(因為變量的取值是需要從原型鏈上遍歷的)。除了每次使用變量都是用var關鍵字外,我們在實際情況下經常遇到這樣一種情況,即有的函數只需要執行一次,其內部變量無需維護,比如UI界面的初始化,那麼我們可以使用閉包:

「前端架構師30天快速掌握js17」之閉包知識點詳解

我們創建了一個匿名的函數,並立即執行它,由於外部無法引用它內部的變量,因此在函數執行完後會立刻釋放資源,關鍵是不汙染全局對象。

  1. 結果緩存

我們開發中會碰到很多情況,設想我們有一個處理過程很耗時的函數對象,每次調用都會花費很長時間,那麼我們就需要將計算出來的值存儲起來,當調用這個函數的時候,首先在緩存中查找,如果找不到,則進行計算,然後更新緩存並返回值,如果找到了,直接返回查找到的值即可。閉包正是可以做到這一點,因為它不會釋放外部的引用,從而函數內部的值可以得以保留。

「前端架構師30天快速掌握js17」之閉包知識點詳解

  1. 封裝

「前端架構師30天快速掌握js17」之閉包知識點詳解

  1. 實現類和繼承

「前端架構師30天快速掌握js17」之閉包知識點詳解

我們定義了Person,它就像一個類,我們new一個Person對象,訪問它的方法。

下面我們定義了Jack,繼承Person,並添加自己的方法。

使用閉包的注意點

  1. 由於閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存洩露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。

  2. 閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。

大家好接下來我們會邀請前端架構師以連載的方式,通過30天的實戰系統講解JavaScript的專業知識,歡迎大家關注頭條號“互聯網IT信息”。


分享到:


相關文章: