日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

闭包 | 浅谈JavaScript闭包问题

發(fā)布時(shí)間:2025/5/22 javascript 71 豆豆
生活随笔 收集整理的這篇文章主要介紹了 闭包 | 浅谈JavaScript闭包问题 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.前言

閉包這個(gè)東西在JavaScript中是一個(gè)很強(qiáng)大的東西,但是在初學(xué)的階段總是被其概念繞暈,搞不清楚到底什么是閉包,感覺(jué)很高深。作者在剛學(xué)的時(shí)候也有一點(diǎn)懵圈,多看幾次就會(huì)有自己的理解。任何東西都沒(méi)有唯一的標(biāo)準(zhǔn),只要適合自己,自己能夠理解的就是正確的。由于作者水平有限,將自己的一些見(jiàn)解拿出來(lái),希望大家能夠提出寶貴的意見(jiàn)。

2.作用域

在正式講閉包之前,我們來(lái)簡(jiǎn)單的說(shuō)一說(shuō)作用域這個(gè)東西。這個(gè)很有助于大家理解后面的閉包。
什么是域?簡(jiǎn)單的說(shuō)就是一個(gè)被圈起來(lái)的地方,也就是變量能夠訪問(wèn)的一個(gè)范圍。
眾所周知,變量的作用域分為全局變量和局部變量。定義在函數(shù)外部的稱為全局變量,在函數(shù)內(nèi)部的稱為局部變量。這里順帶提一下,變量提升這個(gè)玩意兒,也就是和“先聲明后使用差不多的道理”,后面我將會(huì)舉一個(gè)例子來(lái)說(shuō)明。
舉個(gè)例子,全局變量和局部變量:

1 2 3 4 5 6 7 8 9 10 11 12 復(fù)制代碼var a='wang'; function fun(){var b='huagang';console.log('這是在函數(shù)內(nèi)部的輸出');console.log(a);console.log(b); } fun();//調(diào)用函數(shù)console.log("這是在函數(shù)外部的輸出"); console.log(a); console.log(b); 復(fù)制代碼

運(yùn)行結(jié)果:

最后一個(gè)輸出b的時(shí)候拋出了一個(gè)未定義異常,由此可見(jiàn),全局變量(a)在函數(shù)內(nèi)部和外部都是能訪問(wèn)的,但是局部變量不是這樣的,在函數(shù)作用域外是不能訪問(wèn)到函數(shù)內(nèi)部的變量(b)的。這里順帶講一下【變量提升】吧,簡(jiǎn)單的舉一個(gè)例子。

1 2 3 4 復(fù)制代碼var a; console.log(a); a='wang'; console.log(a) 復(fù)制代碼


根據(jù)輸出情況可以看出,第一次輸出a并沒(méi)有報(bào)異常,而是undefined。第二次便能輸出a的值。這就是變量提升的特點(diǎn),在變量還沒(méi)賦值前就拿來(lái)使用了。

3.嵌套函數(shù)的作用域

嵌套函數(shù),顧名思義就是在函數(shù)的內(nèi)部再寫(xiě)一個(gè)或多個(gè)函數(shù)。下面舉一個(gè)例子來(lái)講解一下嵌套函數(shù)的作用域。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 復(fù)制代碼function funA(c){var a='wang';function funB(){var b='gang';console.log("在函數(shù)B中的輸出:")console.log(a);console.log(c);console.log(b);}funB();console.log("在函數(shù)A中的輸出:")console.log(a);console.log(c);console.log(b); } funA('hua');//調(diào)用函數(shù)A并傳參 復(fù)制代碼


函數(shù)B就是嵌套在函數(shù)A中的嵌套函數(shù),它可以繼承函數(shù)A的變量和參數(shù),但是B中的變量A是不能訪問(wèn)的,就好像B給自己的門(mén)上了鎖,“只進(jìn)不出”,我可以拿你的東西,但是你不可以拿我的東西。B這樣就形成了一個(gè)自己獨(dú)有的封閉空間,這就是一個(gè)閉包。
從不同的角度來(lái)看:從語(yǔ)法結(jié)構(gòu)上看,函數(shù)A包含函數(shù)B;從作用域來(lái)看,函數(shù)B包含函數(shù)A,也就是說(shuō)B能訪問(wèn)的空間比A大。
因此可以想象得出,假如B函數(shù)中還有一個(gè)嵌套函數(shù)X,那么這個(gè)X函數(shù)也是一個(gè)閉包,作用域包含B和A。這樣下去就形成了一個(gè)作用域鏈。

4.閉包

相信通過(guò)上面的講解,大家已經(jīng)懂得了什么是閉包,現(xiàn)在再講講一些關(guān)于閉包的特點(diǎn)或者特性吧。

保存變量

什么是保存變量?加入B這個(gè)閉包需要兩個(gè)變量才能運(yùn)行,但是剛開(kāi)始只傳了一個(gè)參數(shù)進(jìn)去,所以這時(shí)候閉包就會(huì)把這個(gè)變量的值進(jìn)行保存,等待第二個(gè)變量傳入,而不是丟棄這個(gè)變量的值。下面舉一個(gè)例子進(jìn)行說(shuō)明吧。

1 2 3 4 5 6 7 8 9 復(fù)制代碼function funA(a){function funB(b){return a + b;}return funB;//調(diào)用函數(shù)B的引用 } var x = funA(2); var sum = x(3); console.log(sum);//輸出結(jié)果 5 復(fù)制代碼


當(dāng)函數(shù)A傳進(jìn)參數(shù)a=2時(shí),這時(shí)閉包B就將a進(jìn)行保存,等到再傳b=3時(shí)再進(jìn)行計(jì)算。這就是閉包的保存變量。

5.為什么要使用閉包

使用閉包的最大的好處——避免變量的污染。也就是說(shuō)你在閉包中聲明的變量不會(huì)影響在其他地方也使用這個(gè)變量名稱,因?yàn)殚]包將這個(gè)變量鎖在自己的門(mén)里面保護(hù)起來(lái)了,外部是無(wú)法修改的。

1 2 3 4 5 6 7 8 9 10 11 復(fù)制代碼function funA(){function funB(b){var a = 'wang';//內(nèi)部變量 creturn a+b ;}return funB; } var a = 'hua';//外部變量x,是不能改變閉包B中的變量a的 var sum = funA()(a); console.log(a); console.log(sum); 復(fù)制代碼


可以看出,外部變量是不能修改閉包中的變量a的值的,從而保護(hù)了a的值,使其不會(huì)受到污染。

閉包的分享就講到這里啦,我相信大家能夠?qū)﹂]包能夠有一定的了解。當(dāng)然,由于作者水平有限,這只是個(gè)人的見(jiàn)解,有誤的地方還希望多多包涵,或者留言告知我。


我的博客地址:【咕嚕先森的博客】

個(gè)人微信公眾號(hào):【咕嚕有得聊】,歡迎關(guān)注,一起學(xué)習(xí)!



總結(jié)

以上是生活随笔為你收集整理的闭包 | 浅谈JavaScript闭包问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。