根據(jù)一段代碼淺談Javascript閉包
更新時(shí)間:2010年12月14日 21:42:45 作者:
水平不高,不能也不想從太深的層次去講解這個(gè)東西,只是根據(jù)一段比較有代表性的代碼,結(jié)合執(zhí)行結(jié)果,從表象上粗淺地談?wù)劇?/div>
function f1(){
var n = 999;
nAdd = function(){ n += 1; }
function f2(){
alert(n);
}
return f2;
}
這里的閉包是f1,封閉了一個(gè)變量n和一個(gè)函數(shù)f2。
我們先無視nAdd,盡量保持原貌重寫一下這個(gè)函數(shù)。
function f1(){
var n = 999;
var f2 = function(){ alert(n); };
return f2;
}
var result = f1();
result();
js中各個(gè)變量以function為單元進(jìn)行封裝,當(dāng)在function內(nèi)部找不到某一變量時(shí),function會(huì)向其所在的上一單元(上下文)中進(jìn)行查找,一直查找到頂層的window域。
這時(shí)就出現(xiàn)一個(gè)疑問:這個(gè)查找過程是以函數(shù)引用位置為起點(diǎn)還是函數(shù)體定義的位置為起點(diǎn)?
在上面這一段代碼中,result所在域是window,但是實(shí)際的輸出結(jié)果是f1內(nèi)部的n值,所以可以得出結(jié)論:變量查找的起點(diǎn)是函數(shù)體定義的位置。
現(xiàn)在再回過頭來看nAdd(第一段代碼)。如我們所知,沒有關(guān)鍵字var定義的變量默認(rèn)進(jìn)入window域,所以nAdd實(shí)際為window.nAdd。這就等同于如下代碼:
var nAdd;
function f1(){
var n = 999;
nAdd = function(){ n += 1; }
function f2(){
alert(n);
}
return function(){ alert(n); };
}
那么根據(jù)我們對(duì)result的分析,nAdd的執(zhí)行將影響f1中n的值。
所以有:
function f1(){
var n = 999;
nAdd = function(){ n += 1; }
function f2(){
alert(n);
}
return function(){ alert(n); };
}
var result = f1();
result();
nAdd();
result();
這段代碼執(zhí)行最終的輸出結(jié)果為1000。
再看這種情況:
function f1(){
var n = 999;
nAdd = function(){ n += 1; }
function f2(){
alert(n);
}
return function(){ alert(n); };
}
f1()(); //<--p1
nAdd();
f1()(); //<--p2
簡述一下執(zhí)行過程:
p1位置,f1封裝了一個(gè)匿名的閉包A,在返回A閉包中的函數(shù)A:f2后繼而執(zhí)行A:f2,A:f2輸出變量A:n,結(jié)果是999。
與此同時(shí),nAdd被賦值為A閉包中的一個(gè)函數(shù),下一行執(zhí)行nAdd即讓A:n的值+1。
p2位置,f1封裝匿名的閉包B,所進(jìn)行的操作都是針對(duì)閉包B的,隨后執(zhí)行B:f2輸出的是B:n,所以最后的結(jié)果依然是999。
A和B是兩個(gè)獨(dú)立的“包”,互不影響。
改寫一下函數(shù)的調(diào)用部分:
function f1(){
var n = 999;
nAdd = function(){ n += 1; }
function f2(){
alert(n);
}
return function(){ alert(n); };
}
var result = f1();
result();
nAdd();
f1()();
result(); // <--p3
p3位置不意外地輸出了1000。
復(fù)制代碼 代碼如下:
function f1(){
var n = 999;
nAdd = function(){ n += 1; }
function f2(){
alert(n);
}
return f2;
}
這里的閉包是f1,封閉了一個(gè)變量n和一個(gè)函數(shù)f2。
我們先無視nAdd,盡量保持原貌重寫一下這個(gè)函數(shù)。
復(fù)制代碼 代碼如下:
function f1(){
var n = 999;
var f2 = function(){ alert(n); };
return f2;
}
var result = f1();
result();
js中各個(gè)變量以function為單元進(jìn)行封裝,當(dāng)在function內(nèi)部找不到某一變量時(shí),function會(huì)向其所在的上一單元(上下文)中進(jìn)行查找,一直查找到頂層的window域。
這時(shí)就出現(xiàn)一個(gè)疑問:這個(gè)查找過程是以函數(shù)引用位置為起點(diǎn)還是函數(shù)體定義的位置為起點(diǎn)?
在上面這一段代碼中,result所在域是window,但是實(shí)際的輸出結(jié)果是f1內(nèi)部的n值,所以可以得出結(jié)論:變量查找的起點(diǎn)是函數(shù)體定義的位置。
現(xiàn)在再回過頭來看nAdd(第一段代碼)。如我們所知,沒有關(guān)鍵字var定義的變量默認(rèn)進(jìn)入window域,所以nAdd實(shí)際為window.nAdd。這就等同于如下代碼:
復(fù)制代碼 代碼如下:
var nAdd;
function f1(){
var n = 999;
nAdd = function(){ n += 1; }
function f2(){
alert(n);
}
return function(){ alert(n); };
}
那么根據(jù)我們對(duì)result的分析,nAdd的執(zhí)行將影響f1中n的值。
所以有:
復(fù)制代碼 代碼如下:
function f1(){
var n = 999;
nAdd = function(){ n += 1; }
function f2(){
alert(n);
}
return function(){ alert(n); };
}
var result = f1();
result();
nAdd();
result();
這段代碼執(zhí)行最終的輸出結(jié)果為1000。
再看這種情況:
復(fù)制代碼 代碼如下:
function f1(){
var n = 999;
nAdd = function(){ n += 1; }
function f2(){
alert(n);
}
return function(){ alert(n); };
}
f1()(); //<--p1
nAdd();
f1()(); //<--p2
簡述一下執(zhí)行過程:
p1位置,f1封裝了一個(gè)匿名的閉包A,在返回A閉包中的函數(shù)A:f2后繼而執(zhí)行A:f2,A:f2輸出變量A:n,結(jié)果是999。
與此同時(shí),nAdd被賦值為A閉包中的一個(gè)函數(shù),下一行執(zhí)行nAdd即讓A:n的值+1。
p2位置,f1封裝匿名的閉包B,所進(jìn)行的操作都是針對(duì)閉包B的,隨后執(zhí)行B:f2輸出的是B:n,所以最后的結(jié)果依然是999。
A和B是兩個(gè)獨(dú)立的“包”,互不影響。
改寫一下函數(shù)的調(diào)用部分:
復(fù)制代碼 代碼如下:
function f1(){
var n = 999;
nAdd = function(){ n += 1; }
function f2(){
alert(n);
}
return function(){ alert(n); };
}
var result = f1();
result();
nAdd();
f1()();
result(); // <--p3
p3位置不意外地輸出了1000。
相關(guān)文章
javascript中attachEvent用法實(shí)例分析
這篇文章主要介紹了javascript中attachEvent用法,實(shí)例分析了javascript中事件綁定的相關(guān)技巧,需要的朋友可以參考下2015-05-05
原生js實(shí)現(xiàn)tab選項(xiàng)卡切換
這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)tab選項(xiàng)卡,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08
教你javascript如何獲取對(duì)象的key和value
獲取對(duì)象所有key的方法,需要使用?Object.keys(obj)?方法,Object.keys(obj)方返回一個(gè)數(shù)組,這個(gè)數(shù)組包含obj對(duì)象中的所有key,這篇文章主要介紹了javascript如何獲取對(duì)象的key和value,需要的朋友可以參考下2022-12-12
微信小程序?qū)㈨撁姘粹o懸浮固定在底部的實(shí)現(xiàn)代碼
這篇文章主要介紹了微信小程序?qū)㈨撁姘粹o懸浮固定在底部的實(shí)現(xiàn)代碼,代碼簡單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
JS實(shí)現(xiàn)仿FLASH效果的豎排導(dǎo)航代碼
這篇文章主要介紹了JS實(shí)現(xiàn)仿FLASH效果的豎排導(dǎo)航代碼,涉及JavaScript基于定時(shí)函數(shù)動(dòng)態(tài)設(shè)置頁面元素樣式的技巧,具有FLASH變換效果,需要的朋友可以參考下2015-09-09

