淺析Javascript閉包的特性

Javascript閉包的定義非乘蓟遥晦澀——閉包半开,是指語法域位于某個特定的區(qū)域,具有持續(xù)參照(讀寫)位于該區(qū)域內自身范圍之外的執(zhí)行域上的非持久型變量值能力的段落枢冤。這些外部執(zhí)行域的非持久型變量神奇地保留它們在閉包最初定義(或創(chuàng)建)時的值(深連結)鸠姨。
簡單來說,Javascript閉包就是在另一個作用域中保存了一份它從上一級函數(shù)或作用域取得的變量(鍵值對)掏导,而這些鍵值對是不會隨上一級函數(shù)的執(zhí)行完成而銷毀享怀。周愛民說得更清楚羽峰,閉包就是“屬性表”趟咆,閉包就是一個數(shù)據(jù)塊,閉包就是一個存放著“Name=Value”的對照表梅屉。就這么簡單值纱。但是,必須強調坯汤,閉包是運行期概念虐唠,一個函數(shù)實例。
Javascript閉包的實現(xiàn)惰聂,通常是在函數(shù)內部再定義函數(shù)疆偿,讓該內部函數(shù)使用上一級函數(shù)的變量或全局變量。
ECMAScript認為使用全局變量是一個簡單的Javascript閉包實例搓幌。

1.  **var** sMessage = "Hello World";   
2.  **function** sayHelloWorld(){   
3.  alert(sMessage);   
4.  };   
5.  sayHelloWorld(); 

但它完成沒有體現(xiàn)Javascript閉包的特性……
現(xiàn)在比較讓人認同的Javascript閉包實現(xiàn)有如下三種

1.  **with**(obj){   
2.  //這里是對象閉包   
3.  }(**function**(){      
4.  //函數(shù)閉包   
5.  })()**try**{   
6.  //...   
7.  } **catch**(e) {   
8.  //catch閉包 但IE里不行   
9.  } 

附上我們常常遇到的問題:
要求:
讓這三個節(jié)點的Onclick事件都能正確的彈出相應的參數(shù)杆故。

1.  <ul>
2. <li id="a1">aa</li>   
3.  <li id="a2">aa</li>   
4.  <li id="a3">aa</li>   
5.  </ul>   
6.  <script** type="text/javascript">   
7.  <ul>   
8.  <li id="a1">aa</li>  
9.  <li id="a2">aa</li>   
10. <li id="a3"*>aa</li>  
11.</ul>   
12. <script** type="text/javascript"**>**   
13. for(var i=1; i **< 4**; i++){   
14. var id = document.getElementById("a" + i);   
15. id.onclick = function(){   
16. alert(i);//現(xiàn)在都是返回4      
17. }   
18. }   
19. </script> 

解答:

  1. for(var i=1; i < 4; i++){
  2. var id = document.getElementById("a" + i);
  3. /*
  4. 這里生成了一個匿名函數(shù)并賦值給對象 id_i;
  5. */
  6. id.onclick = function(){
  7. /*
  8. 這個i來源于局部變量,無法以window.i或者obj.i的形式在后期引用溉愁,
  9. 只好以指針或者變量地址方式保存在這個匿名函數(shù)中处铛,
  10. 這就是傳說的閉包,所以所有這個過程中生成的事件句柄都使用引用
  11. 的方式來持久這個變量,也就是這些匿名函數(shù)共用一個變量i;
  12. */
  13. alert(i);
  14. };
  15. };
    局部變全局
  16. for(var i=1; i < 4; i++){
  17. var id = document.getElementById("a" + i);
  18. id.i=i;//這個i有了根
  19. id.onclick=function(){
  20. alert(this.i)
  21. };
  22. };1.for(var i=1; i < 4; i++){
  23. var id = document.getElementById("a" + i);
  24. window[id.id]=i;//這個i有了根
  25. id.onclick=function(){
  26. alert(window[this.id]);
  27. };
  28. }
    產(chǎn)生一對一的更多Javascript閉包
  29. for(var i=1; i < 4; i++){
  30. var id = document.getElementById("a" + i);
  31. id.onclick = new function(){
  32. var i2=i;//這個i是閉包的閉包
  33. return function(){
  34. alert(i2);
  35. }
  36. };
  37. }
    javascript深入理解js閉包發(fā)布:dxy 字體:[增加 減小] 類型:轉載

閉包(closure)是Javascript語言的一個難點撤蟆,也是它的特色奕塑,很多高級應用都要依靠閉包實現(xiàn)。

一家肯、變量的作用域

要理解閉包龄砰,首先必須理解Javascript特殊的變量作用域。

變量的作用域無非就是兩種:全局變量和局部變量讨衣。

Javascript語言的特殊之處寝贡,就在于函數(shù)內部可以直接讀取全局變量。

Js代碼

var n=999;

function f1(){
    alert(n);
  }

f1(); // 999

另一方面值依,在函數(shù)外部自然無法讀取函數(shù)內的局部變量圃泡。

Js代碼

function f1(){
    var n=999;
  }

alert(n); // error

這里有一個地方需要注意,函數(shù)內部聲明變量的時候愿险,一定要使用var命令颇蜡。如果不用的話,你實際上聲明了一個全局變量辆亏!

Js代碼

function f1(){
    n=999;
  }

f1();

alert(n); // 999


二风秤、如何從外部讀取局部變量?

出于種種原因扮叨,我們有時候需要得到函數(shù)內的局部變量缤弦。但是,前面已經(jīng)說過了彻磁,正常情況下碍沐,這是辦不到的,只有通過變通方法才能實現(xiàn)衷蜓。

那就是在函數(shù)的內部累提,再定義一個函數(shù)。

Js代碼

function f1(){

n=999;

function f2(){
      alert(n); // 999
    }

}

在上面的代碼中磁浇,函數(shù)f2就被包括在函數(shù)f1內部斋陪,這時f1內部的所有局部變量,對f2都是可見的置吓。但是反過來就不行无虚,f2內部的局部變量,對f1 就是不可見的衍锚。這就是Javascript語言特有的“鏈式作用域”結構(chain scope)友题,

子對象會一級一級地向上尋找所有父對象的變量。所以构拳,父對象的所有變量咆爽,對子對象都是可見的梁棠,反之則不成立。

既然f2可以讀取f1中的局部變量斗埂,那么只要把f2作為返回值符糊,我們不就可以在f1外部讀取它的內部變量了嗎!

Js代碼

function f1(){

n=999;

function f2(){
      alert(n);
    }

return f2;

}

var result=f1();

result(); // 999


三呛凶、閉包的概念

上一節(jié)代碼中的f2函數(shù)男娄,就是閉包。

各種專業(yè)文獻上的“閉包”(closure)定義非常抽象漾稀,很難看懂模闲。我的理解是,閉包就是能夠讀取其他函數(shù)內部變量的函數(shù)崭捍。

由于在Javascript語言中尸折,只有函數(shù)內部的子函數(shù)才能讀取局部變量,因此可以把閉包簡單理解成“定義在一個函數(shù)內部的函數(shù)”殷蛇。

所以实夹,在本質上,閉包就是將函數(shù)內部和函數(shù)外部連接起來的一座橋梁粒梦。

--------------------------------------------------------------------------------------------------------b

四亮航、閉包的用途

閉包可以用在許多地方。它的最大用處有兩個匀们,一個是前面提到的可以讀取函數(shù)內部的變量缴淋,另一個就是讓這些變量的值始終保持在內存中。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末泄朴,一起剝皮案震驚了整個濱河市重抖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌叼旋,老刑警劉巖仇哆,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異夫植,居然都是意外死亡,警方通過查閱死者的電腦和手機油讯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門详民,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人陌兑,你說我怎么就攤上這事沈跨。” “怎么了兔综?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵饿凛,是天一觀的道長狞玛。 經(jīng)常有香客問我,道長涧窒,這世上最難降的妖魔是什么心肪? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮纠吴,結果婚禮上硬鞍,老公的妹妹穿的比我還像新娘。我一直安慰自己戴已,他們只是感情好固该,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著糖儡,像睡著了一般伐坏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上握联,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天著淆,我揣著相機與錄音,去河邊找鬼拴疤。 笑死永部,一個胖子當著我的面吹牛,可吹牛的內容都是我干的呐矾。 我是一名探鬼主播苔埋,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蜒犯!你這毒婦竟也來了组橄?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤罚随,失蹤者是張志新(化名)和其女友劉穎玉工,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淘菩,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡遵班,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了潮改。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狭郑。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖汇在,靈堂內的尸體忽然破棺而出翰萨,到底是詐尸還是另有隱情,我是刑警寧澤糕殉,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布亩鬼,位于F島的核電站殖告,受9級特大地震影響,放射性物質發(fā)生泄漏雳锋。R本人自食惡果不足惜黄绩,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望魄缚。 院中可真熱鬧宝与,春花似錦、人聲如沸冶匹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嚼隘。三九已至诽里,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間飞蛹,已是汗流浹背谤狡。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留卧檐,地道東北人墓懂。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像霉囚,于是被迫代替她去往敵國和親捕仔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內容

  • 閉包(closure)是Javascript語言的一個難點盈罐,也是它的特色榜跌,很多高級應用都要依靠閉包實現(xiàn)。 一盅粪、變量...
    zock閱讀 1,074評論 2 6
  • 閉包(closure)是Javascript語言的一個難點钓葫,也是它的特色,很多高級應用都要依靠閉包實現(xiàn)票顾。 一础浮、變量...
    zouCode閱讀 1,270評論 0 13
  • ● 閉包基礎 ● 閉包作用 ● 閉包經(jīng)典例子 ● 閉包應用 ● 閉包缺點 ● 參考資料 1、閉包基礎 作用域和作...
    lzyuan閱讀 921評論 0 0
  • 閉包(closure)是Javascript語言的一個難點库物,也是它的特色霸旗,很多高級應用都要依靠閉包實現(xiàn)。 下面就是...
    魯uin閱讀 297評論 0 2
  • 十八怪戚揭,原生態(tài), 樹折樹倒由它擺撵枢。 身臥寧靜數(shù)星辰民晒, 骨化沃土伴林海精居。 這也怪,那也怪潜必, 少見自然就多怪靴姿。 一方水...
    珠江潮平閱讀 311評論 20 26