您好,登錄后才能下訂單哦!
本篇內容主要講解“JS閉包的知識點詳解”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JS閉包的知識點詳解”吧!
一、什么是閉包?
學習一個陌生的概念,我們首先要去明白是什么?也就是閉包是什么?要想完全掌握閉包,一定要清楚函數作用域、內存回收機制、作用域繼承。我們就簡單講一下這幾個概念。
1. 函數作用域
作用域的概念,形象描述的話,可以認為它是一個封閉的空間,只允許在這個封閉的空間內進行一些操作,也將這個封閉空間稱為私有作用域。在 JS 中,一個函數的執行就會在內存中創建一個私有作用域——封閉的空間。
比如在函數中定義一個變量,只能在函數這個私有作用域中使用(也就是封閉空間)。只要超出了這個作用域,就找不到該變量了。
而且函數執行完成后,這個私有作用域(封閉的空間)就會銷毀。有一種情況它是不會銷毀的,那就是“閉包”,后邊會講到。
2. 內存回收機制
內存回收機制就是不在用到的內存,我們系統就自動進行回收從而清理出空間供其他程序使用。那回收的規則是什么?
內部函數引用著外部的函數的變量,外部的函數盡管執行完畢,作用域也不會銷毀。從而形成了一種不銷毀的私有作用域。
某一變量或者對象被引用著,因此在回收的時候不會釋放它,因為被引用代表著被使用,回收器不會對正在引用的變量或對象回收的。
3. 作用域繼承
所謂的作用域繼承,就像是兒子可以繼承父親的財產一樣。比如小鹿這里有一個大的盒子作為一個父級的作用域,然后在這個大的盒子里邊放一個小的盒子,作為子作用域。我們規定可以在小盒子中獲取到大盒子中的東西,大盒子不能獲取小盒子里的東西就稱為作用域繼承。
在 JS 中,道理是一樣的,在一個函數里邊我們再聲明一個函數,內部函數可以訪問外部函數作用域的變量,而外部的函數不能獲取到內部函數的作用域變量。
那好,上邊的這幾個概念理解了之后,什么是閉包對你來說已經不是什么問題。
大白話說什么是閉包,那就是在一個函數里邊再定義一個函數。這個內部函數一直保持有對外部函數中作用域的訪問權限(小盒子一直可以有大盒子的訪問權限)。
函數執行,形成一個私有的作用域,保護里邊的私有變量不受外界的干擾,除了保護私有變量外,還可以存儲一些內容,這樣的模式叫做閉包。
動畫實現:
二、閉包的作用是什么?
想必你對閉包還是有點懵懵懂懂,沒關系,我們再繼續深入了解。閉包主要的作用是什么呢?為什么要使用閉包呢?
通過上邊對閉包的解釋,外部函數 return 內部函數,但是仍然還是可以有訪問外部函數的作用域,因為外部一直保持著引用。這就讓我們發現它的可用之處。
不是有塊作用域不銷毀嗎?我們可以用來保存一些內容,還可以用來保護一些私有的變量。我們總結出閉包有兩個作用,分別為保護和保存。
三、閉包的應用場景
既然我們知道閉包的作用是保存和保護,那在實際項目中哪里用到了呢?
1. 保護作用
團隊開發時,每個開發者把自己的代碼放在一個私有的作用域中,防止相互之間的變量命名沖突;把需要提供給別人的方法,通過 return 或 window.xxx 的方式暴露在全局下。
jQuery 的源碼中也是利用了這種保護機制。
2. 保存作用
選項卡閉包的解決方案。我們經常在網頁中使用選項卡,但是它存在一個問題,那就是索引引發的問題,其實和下邊的經典面試題問題相同。
四、經典的閉包面試題
循環綁定事件引發的索引什么問題?怎么解決這種問題?
此時運行程序,你會得出的結果都是 len 的數值。
為什么會出現這種問題,我們如何解決呢?
原因很簡單,所有的事件綁定都是異步的,當觸發點擊事件,執行方法的時候,循環早就結束了。
我們在多說一點,什么是同步什么是異步?
同步:JS 中當前這個任務沒有完成,下面的任務都不會執行,只有等當前徹底完成,才會執行下面的任務。
異步:JS 中的當前任務沒有完成,需要等一會在完成,此時我們可以繼續執行下面的任務。
解決方案:
當點擊事件執行的時候,就會在私有作用域查找 i 的值,此時私有作用域沒有 i ,就回去全局作用域查找,此時全局作用域的 i 已經被改變。所以說,要創建一個私有作用域的 i 。
方法一,閉包的方式。閉包終于排上用場了,用來保存私有的變量。
但是閉包解決又優點,也有缺點。優點就是通過創建私有作用域(閉包)方式解決,循環幾次,就創建幾個私有作用域(閉包),然后,每個私有作用域都有一個私有變量 i ,存的值分別是循環的值。
缺點是生成多個不銷毀的私有作用域(堆內存),對性能有一定的影響。
方法二,使用自定義屬性。我們給每個對象添加一個索引屬性就 OK 了。
終極解決方案,這是 ES6 中的知識,因為之前在 JS 中是沒有塊級作用域的概念的,到了 ES6 中就有了,Let 聲明的變量就可以更好的解決上述問題。
到此,相信大家對“JS閉包的知識點詳解”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。