JavaScript防止全局變量污染的方法總結(jié)
本文實(shí)例講述了JavaScript防止全局變量污染的方法。分享給大家供大家參考,具體如下:
javaScript 可以隨意定義保存所有應(yīng)用資源的全局變量。但全局變量可以削弱程序靈活性,增大了模塊之間的耦合性。
在多人協(xié)作時(shí),如果定義過(guò)多的全局變量 有可能造成全局變量沖突,也就是全局變量污染問(wèn)題,以下是兩種解決辦法
一. 定義全局變量命名空間
只創(chuàng)建一個(gè)全局變量,并定義該變量為當(dāng)前應(yīng)用容器,把其他全局變量追加在該命名空間下
var MY={};
my.name={
big_name:"zhangsan",
small_name:"lisi"
};
my.work={
school_work:"study",
family_work:"we are"
};
二 . 利用匿名函數(shù)將腳本包裹起來(lái)
(function(){
var exp={};
var name="aa";
exp.method=function(){
return name;
};
window.ex=exp;
})();
前言
記得long long ago,剛剛開(kāi)始寫(xiě)JS的時(shí)候,我喜歡寫(xiě)一些函數(shù)在JS文件里邊,然后通過(guò)script標(biāo)簽引進(jìn)來(lái),在DOM節(jié)點(diǎn)上綁定onclick等事件,看了很多人寫(xiě)的代碼,也大多是這樣。
后來(lái)會(huì)發(fā)現(xiàn),當(dāng)項(xiàng)目小的時(shí)候這么做為了快速開(kāi)發(fā)是可以接受的,然而當(dāng)很多人一起開(kāi)發(fā)一個(gè)Javascript大應(yīng)用的時(shí)候,你會(huì)發(fā)現(xiàn)不同的代碼風(fēng)格跟全局變量會(huì)導(dǎo)致很多沖突,這是一個(gè)很痛苦的事情。
曾經(jīng)的經(jīng)歷
用過(guò)jQuery的人就知道其主要的變量符號(hào)就是$,沒(méi)錯(cuò)!因此很多項(xiàng)目的開(kāi)發(fā)人員也要學(xué),就自己把$定義成別的含義了,我心里對(duì)其是無(wú)敵的鄙視跟厭惡。
我曾經(jīng)拿過(guò)一個(gè)項(xiàng)目使用jQuery的,然后上頭要我使用一個(gè)已有的富文本編輯器,這樣就有兩個(gè)JS文件了
jquery.js和editor.js,于是我要開(kāi)始寫(xiě)該頁(yè)面的邏輯了,我發(fā)現(xiàn)editor.js里邊自定義了$符號(hào),我原本想要把它直接替換成別的標(biāo)志符,但是悲劇的是,它還有一些插件也會(huì)用到,混亂的結(jié)構(gòu)導(dǎo)致我花了很多時(shí)間去解決這個(gè)沖突。
全局Window
我們都知道,在文件中直接定義的變量跟函數(shù)(不嵌套在任何域底下的)都是屬于全局的,也就是都在當(dāng)前頁(yè)面的window變量底下。例如:
JS代碼
function test1(){
}
var name;
function test2(){
i = 1;
}
上邊代碼中的name,test1,test2和i都是屬于window底下的全局變量,也就是可以通過(guò)以下三種辦法訪問(wèn)到它們:
1.直接訪問(wèn)name,test1()等;
2.使用window["name"], window['test1']()等;
3.使用window.name,window.test1()等。
注意:上邊代碼中的i雖然是在test2函數(shù)里邊才出現(xiàn)的,因?yàn)槠淝懊鏇](méi)有使用var關(guān)鍵字,解釋器會(huì)認(rèn)為它在test2的上一層定義的,依次查找上一層,直到找到window全局,如果發(fā)現(xiàn)還是未定義,那么將其掛在window底下成為了全局變量。
所以你直接定義的函數(shù)通通都掛到了window底下,這就是一種污染了,當(dāng)很多人定義各種變量跟函數(shù),你又得同時(shí)引入進(jìn)來(lái)的時(shí)候,這個(gè)沖突的概率就變大了。
減少污染
那為了避免過(guò)多這樣的沖突,以及模塊之間的耦合性更低,需要減少這樣的污染。
此時(shí)我們會(huì)想,那不要把變量定義在全局唄,采用類(lèi)似C++的命名空間,Java的包的思路就行啦。
首先就是將不同的模塊劃入到不同的全局“包”(這里的包的概念實(shí)際上就是一個(gè)Javascript對(duì)象而已)。
例如,程序員A為全局添加一個(gè)A變量,然后他把自己定義的函數(shù)/變量全部掛到A底下,這樣就跟程序員B所定義的隔離了。
再者我們可以使用函數(shù)域來(lái)隔離一些局部變量的沖突,比如說(shuō)程序員A寫(xiě)的代碼如下:
JS代碼:
(function(obj){
/* 在這里邊就與外邊隔離了,定義的局部變量不會(huì)與外界干擾 */
/* 為了跟外界達(dá)到共享的目的,還可以為其加入?yún)?shù),例如obj,在最后調(diào)用的時(shí)候把相關(guān)的參數(shù)傳進(jìn)來(lái),例如下邊的window */
var A = {};//定義一個(gè)A包
var tmp;//臨時(shí)變量
A.i = 1;//定義這個(gè)包里邊的i變量
A.func = function(){alert('I am A');};
obj.A = A;/* 把A包掛到obj底下 */
})(window);
當(dāng)離開(kāi)了這個(gè)函數(shù)域之后,tmp等局部變量被銷(xiāo)毀(只要不要存在在閉包里邊),程序員A定義的東西通通掛到了變量window.A底下,從而減少了很多污染,避免了不必要的沖突。
回到過(guò)去
再次回到剛剛提過(guò)的那個(gè)經(jīng)歷,如果我現(xiàn)在為editor.js整個(gè)包圍在function里邊,通過(guò)這種方式把$給隱藏在一個(gè)包里邊,在它的其他控件中也采取這樣的做法,當(dāng)然還要做一小點(diǎn)改動(dòng):
JS代碼:
/* editor.js */
(function(obj){
/* 原先editor里邊的內(nèi)容 */
/* 里邊有定義了自己的$標(biāo)志 */
obj.editor = obj.editor || {};//如果沒(méi)有editor對(duì)象,則生成一個(gè)空對(duì)象
obj.editor.$ = $;//把$掛在全局的editor對(duì)象上
})(window);
JS代碼:
/* 其他控件.js */
(function(obj){
var $ = obj.$;//把$恢復(fù)
/* 原先控件的內(nèi)容 */
})(window.editor);
當(dāng)然咯,如果editor.js有些功能需要暴露到全局的話,還需要將其進(jìn)一步的掛在editor變量底下,這里只是一個(gè)示范。
本篇總結(jié)
很多框架都采用了這種做法減少全局污染,可能很多人一開(kāi)始對(duì)這種做法有疑惑,這里只是個(gè)人理解拿出來(lái)分享一下,繼續(xù)歡迎交流。
更多關(guān)于JavaScript相關(guān)內(nèi)容可查看本站專(zhuān)題:《JavaScript常用函數(shù)技巧匯總》、《javascript面向?qū)ο笕腴T(mén)教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
- 實(shí)例講解JavaScript預(yù)編譯流程
- JavaScript 詳解預(yù)編譯原理
- JavaScript運(yùn)行過(guò)程中的“預(yù)編譯階段”和“執(zhí)行階段”
- 通過(guò)JSP的預(yù)編譯消除性能瓶頸
- AngularJS基于provider實(shí)現(xiàn)全局變量的讀取和賦值方法
- JS全局變量和局部變量最新解析
- 淺談JavaScript的全局變量與局部變量
- Angularjs全局變量被作用域監(jiān)聽(tīng)的正確姿勢(shì)
- javascript中局部變量和全局變量的區(qū)別詳解
- 淺析JavaScript預(yù)編譯和暗示全局變量
相關(guān)文章
JavaScript中數(shù)組的各種操作的總結(jié)(必看篇)
下面小編就為大家?guī)?lái)一篇JavaScript中數(shù)組的各種操作的總結(jié)(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
js實(shí)現(xiàn)仿MSN帶關(guān)閉功能的右下角彈窗代碼
這篇文章主要介紹了js實(shí)現(xiàn)仿MSN帶關(guān)閉功能的右下角彈窗代碼,涉及javascript操作頁(yè)面元素的布局及屬性的動(dòng)態(tài)變換技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
Popup彈出框添加數(shù)據(jù)實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了Popup彈出框添加數(shù)據(jù)的簡(jiǎn)單實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
微信小程序的數(shù)據(jù)存儲(chǔ)與Django等服務(wù)發(fā)送請(qǐng)求?講解
這篇文章主要為大家介紹了微信小程序的數(shù)據(jù)存儲(chǔ)與Django等服務(wù)發(fā)送請(qǐng)求講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
利用Webpack實(shí)現(xiàn)小程序多項(xiàng)目管理的方法
這篇文章主要介紹了利用Webpack實(shí)現(xiàn)小程序多項(xiàng)目管理的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
js實(shí)現(xiàn)動(dòng)態(tài)增加文件域表單功能
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)動(dòng)態(tài)增加文件域表單功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10
canvas實(shí)現(xiàn)十二星座星空?qǐng)D
本文主要分享了canvas實(shí)現(xiàn)十二星座星空?qǐng)D的示例代碼。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02
js簡(jiǎn)單網(wǎng)速測(cè)試方法完整實(shí)例
這篇文章主要介紹了js簡(jiǎn)單網(wǎng)速測(cè)試方法,以完整實(shí)例形式分析了JavaScript基于網(wǎng)頁(yè)圖片下載進(jìn)行測(cè)試網(wǎng)速的實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-12-12
js+CSS 圖片等比縮小并垂直居中實(shí)現(xiàn)代碼
本例子在在 ff 2.0/ ie6 / ie7 中測(cè)試通過(guò)。但在 opera 8.5 cn中沒(méi)有通過(guò)。希望大家測(cè)試。2008-12-12

