在理解閉包前,首先要搞清楚兩個概念碉渡,作用域和作用域鏈。
一母剥、作用域
簡單理解:作用域就是變量的可用范圍(scope)滞诺。
目的:防止不同范圍內(nèi)的變量之間相互干擾。
js中的作用域有兩種:
1.全局作用域环疼。
不屬于任何函數(shù)的外部范圍习霹。
全局變量:保存在全局作用域的變量。
全局變量 優(yōu)點(diǎn):可反復(fù)使用炫隶。 缺點(diǎn):全局污染序愚。
2.函數(shù)作用域。(ES6的塊級作用域?qū)嶋H上也是函數(shù)作用域)
在函數(shù)內(nèi)部的范圍等限。
局部變量:保存在函數(shù)內(nèi)部的變量爸吮。
函數(shù)內(nèi)部的局部變量只有兩種情況:一種是函數(shù)的形參,一種是函數(shù)內(nèi)部var望门,let 聲明的變量形娇。
局部變量 優(yōu)點(diǎn):不會被污染。缺點(diǎn):不能重復(fù)使用筹误。
說明:只有函數(shù)的{}桐早,才能形成作用域。
比如 對象
二、作用域鏈
簡單理解:每個函數(shù)在定義時哄酝,就已經(jīng)規(guī)劃好了自己專屬的查找變量的路線圖友存,稱為作用域鏈。
內(nèi)部作用域訪問外部作用域的變量陶衅,采取的是鏈?zhǔn)讲檎业姆绞經(jīng)Q定取哪個值屡立,原則是就近查找,向上一級一級的作用域來查找變量搀军,最頂部就是全局作用域膨俐。如果全局作用域沒有找到,那么就會報錯罩句。
三焚刺、作用域的本質(zhì):
全局作用域:其實(shí)是一個window的對象,所有的全局變量和全局函數(shù)都是window對象的成員门烂。
函數(shù)作用域:js引擎調(diào)用函數(shù)時才臨時創(chuàng)建的一個作用域?qū)ο笕橛洹@锩姹4嬷植孔兞浚?dāng)函數(shù)調(diào)用完畢后屯远,函數(shù)作用域?qū)ο箅S之也被釋放掉匾委。(函數(shù)作用域?qū)ο筮€有個別名:活動的對象 Actived Object 簡稱AO),因此局部變量不可重復(fù)使用氓润。
四、閉包
簡單理解:既可以重復(fù)使用變量薯鳍,又保護(hù)變量不被污染的一種編程方法咖气。
以后:只希望給一個函數(shù),保存一個既可以反復(fù)使用挖滤,又不被外界污染的專屬局部變量時崩溪,就用閉包。
閉包三部曲:
1.用外層函數(shù)包裹斩松,要保護(hù)的局部變量和使用變量的內(nèi)層函數(shù)伶唯。
2.在外層函數(shù)內(nèi)部,返回內(nèi)層函數(shù)對象惧盹。
3.調(diào)用外層函數(shù)乳幸,用變量借助返回的內(nèi)層函數(shù)對象。
什么是閉包:
閉包也是一個對象钧椰,就是每次調(diào)用外層函數(shù)時粹断,臨時創(chuàng)建的函數(shù)作用域?qū)ο蟆?br>
為什么外層函數(shù)的作用域?qū)ο竽芰粝聛恚驗(yàn)楸粌?nèi)層函數(shù)的作用域鏈引用著嫡霞,無法釋放瓶埋。
一句話形容閉包:外層函數(shù)調(diào)用后,外層函數(shù)的作用域?qū)ο螅粌?nèi)層函數(shù)的作用域鏈引用著养筒,無法釋放曾撤,因此形成了閉包。
缺點(diǎn):因?yàn)闊o法釋放晕粪,容易造成內(nèi)存泄漏挤悉。
解決辦法:將保存內(nèi)層函數(shù)的對象變量賦值為null。