大家好,我是IT修真院深圳分院第01期學(xué)員,一枚正直善良的web程序員。
今天給大家分享一下,修真院官網(wǎng) JS任務(wù)中可能會使用到的知識點:
閉包是什么?用處如何?
1.背景介紹
閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù)。
創(chuàng)建閉包的常見方式,就是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)。
閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),可以把閉包簡單理解成 ‘定義在一個函數(shù)內(nèi)部的函數(shù)’
先拋開對于兩個出處的具體描述,至少兩者對于閉包的定義可以簡化為:
“閉包是一種函數(shù)”,而且閉包是一種特殊的函數(shù)。
以上兩個出處涉及到了一些概念(或名詞):函數(shù)、內(nèi)部變量、函數(shù)內(nèi)部、函數(shù)作用域
閉包(closure)是Javascript語言的一個難點,也是它的特色,很多高級應(yīng)用都要依靠閉包實現(xiàn)。
JS函數(shù)的執(zhí)行依賴于變量作用域, 函數(shù)對象的內(nèi)部狀態(tài)包含函數(shù)自身的邏輯,還必須引用當(dāng)前的作用域鏈。
閉包是「函數(shù)」和「函數(shù)內(nèi)部能訪問到的變量」(也叫環(huán)境)的總和。
函數(shù)對象可以相互關(guān)聯(lián)起來,函數(shù)體內(nèi)部的變量可以保存在函數(shù)作用域內(nèi), 具有這種特性的函數(shù)稱為閉包。
2.知識剖析
2.1
閉包可以用在許多地方。它的最大用處有兩個:
1.可以讀取函數(shù)內(nèi)部的變量
2.讓這些變量的值始終保存在內(nèi)存中
2.2
變量的作用域
變量的作用域無非就是兩種:全局變量和局部變量。
Javascript語言的特殊之處,就在于函數(shù)內(nèi)部可以直接讀取全局變量。
值得注意的是在局部變量中定義變量的時候要使用var ,不然你聲明的其實是一個全局變量
讀取函數(shù)內(nèi)部的變量的例子:
? ? ? ?在上面的代碼中,函數(shù)f2就被包括在函數(shù)f1內(nèi)部,這時f1內(nèi)部的所有局部變量,對f2都是可見的。但是反過來就不行,f2內(nèi)部的局部變量,對f1就是不可見的。這就是Javascript語言特有的"鏈式作用域"結(jié)構(gòu)(chain scope),子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立。既然f2可以讀取f1中的局部變量,那么只要把f2作為返回值,我們不就可以在f1外部讀取它的內(nèi)部變量了嗎
變量的值始終保存在內(nèi)存的例子:
? ? ? ?在這段代碼中,result實際上就是閉包f2函數(shù)。它一共運行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數(shù)f1中的局部變量n一直保存在內(nèi)存中,并沒有在f1調(diào)用后被自動清除。因為f1是f2的父函數(shù),而f2被賦給了一個全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中,不會在調(diào)用結(jié)束后,被垃圾回收機制(garbage collection)回收。這段代碼中另一個值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒有使用var關(guān)鍵字,因此nAdd是一個全局變量,而不是局部變量。其次,nAdd的值是一個匿名函數(shù)(anonymous function),而這個匿名函數(shù)本身也是一個閉包,所以nAdd相當(dāng)于是一個setter,可以在函數(shù)外部對函數(shù)內(nèi)部的局部變量進行操作。
3.常見問題
如何從外部讀取局部變量?
4.解決方案
很多情況,我們需要使用到函數(shù)內(nèi)的局部變量。
但是,前面已經(jīng)說過了,正常情況下,這是辦不到的,只有通過變通方法才能實現(xiàn)。
因為作用域鏈的關(guān)系,解決思路就是在函數(shù)的內(nèi)部,再定義一個函數(shù)。
5.編碼實戰(zhàn)
6.擴展思考
內(nèi)存泄漏的原因:執(zhí)行這段代碼的時候,將匿名函數(shù)對象賦值給el的onclick屬性;然后匿名函數(shù)內(nèi)部又引用了el對象,存在循環(huán)引用,所以不能被垃圾回收機制回收;
修改后:
7.參考文獻
參考一:(轉(zhuǎn))學(xué)習(xí)JavaScript閉包(阮一峰)
參考二:作用域鏈與閉包
8.更多討論
一、閉包與內(nèi)存泄漏
二、在閉包中的this指向問題
三、閉包的利與弊主要指什么