關(guān)于javascript閉包

閉包的概念比較抽象,理解起來比較困難,但是仔細(xì)分析一下其實也沒有特別恐怖,面向?qū)ο蟮母拍疃几愣诉@又算啥呢

定義:簡單的說就是定義在函數(shù)內(nèi)部的函數(shù),具有讀取局部變量的能力

從這個概念上可以看出閉包涉及到的js概念有:作用域鏈(局部變量) / 函數(shù)的嵌套(定義在函數(shù)內(nèi)部的函數(shù))/內(nèi)存回收(這個比較難理解)

作用域鏈

作用域鏈?zhǔn)呛瘮?shù)聲明的時候創(chuàng)建的,用于尋找使用到的變量的值的一個索引,他內(nèi)部的規(guī)則是,把自己函數(shù)內(nèi)部的變量放在最前面優(yōu)先讀取,把父級函數(shù)的內(nèi)部變量放在其次,然后依次向上排列,直到全局變量,

如果在子函數(shù)內(nèi)部使用一個變量,如果自己函數(shù)內(nèi)部沒有,則去父級函數(shù)內(nèi)尋找,依次向上,如果函數(shù)內(nèi)部沒有則查看全局變量,全局變量如果也沒有則只為undefine,如果找到了則停止尋找;

var a =0;

function fun1(){

? ?var a=1;

? ?function fun2(){

? ? ? ?var a=2;

? ? ? ?alert(a);

? }

? ?fun2()

}

fun1() //-->2

內(nèi)存回收

函數(shù)運行的時候會為函數(shù)內(nèi)部聲明的變量創(chuàng)建內(nèi)存空間,以備后面的語句調(diào)用,函數(shù)運行結(jié)束后則認(rèn)為這些變量已經(jīng)使用完畢,于是變量被銷毀,再次執(zhí)行的時候則內(nèi)存重新創(chuàng)建;

如果函數(shù)的內(nèi)部又嵌套了另一個函數(shù),而且這個函數(shù)有可能在外部被調(diào)用到,還用到了外部函數(shù)的一些變量上面提到的內(nèi)存回收機(jī)制就會失效,也就是說內(nèi)存不在回收了,

如果外部的函數(shù)調(diào)用后又直接調(diào)用了內(nèi)部函數(shù),如果按之前的內(nèi)存回收的話,內(nèi)部函數(shù)就無法讀區(qū)到外部函數(shù)的變量的值了,這時候js解釋器在遇到這種情況時就會把外部的函數(shù)保存起來以保證自己內(nèi)部的變量不被回收,從而能保證內(nèi)部的函數(shù)能夠正常的調(diào)用,其實這種情況就形成了一個閉包,如果內(nèi)部的函數(shù)被銷毀,或者沒有調(diào)用的可能性后閉包也就被回收了;

var test = [];

var i= 0;

for (;i<3;i=i+1){

? ? test[i]=function(){

? ? ? ? alert(i)

? ? ?}

test[0] //3

test[1] //3

test[2] //3

閉包:

var test = [];

var i= 0;

for (;i<3;i=i+1){

? ? test[i]=(function(j){

? ? ? ? ?alert(j)

? ? ?})(i)

test[0] //0

test[1] //1

test[2] //2

test實際上就是閉包fun2函數(shù)。它一共運行了兩次,第一次的值是9,第二次的值是10。這證明了,函數(shù)fun1中的局部變量n一直保存在內(nèi)存中,并沒有在fun1調(diào)用后被自動清除,原因就在于fun1是fun2的父函數(shù),而fun2被賦給了一個全局變量,這導(dǎo)致fun2始終在內(nèi)存中,而fun2的存在依賴于fun1,因此fun1也始終在內(nèi)存中,不會在調(diào)用結(jié)束后,被內(nèi)存回收機(jī)制(garbage collection)回收

function fun1(){

? ? var n=9;

? ? ?add=function(){n+=1}//這里的add是一個全局變量,相當(dāng)于fun1函數(shù)的setter方法,也是一個閉包

? ? function fun2(){

? ? ? ? ? alert(n);

? ? ?}

? ? return fun2;

}

var test=fun1();

test(); // 9

add();

test(); // 10

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。