忘記var的影響
使用var聲明的全局變量和沒(méi)有使用var生成的全局變量還有一個(gè)區(qū)別在于刪除:
使用var聲明創(chuàng)建的全局變量不能被刪除
沒(méi)有使用var聲明的全局變量可以被刪除
這說(shuō)明沒(méi)有使用var聲明生成的全局變量不是真正的變量,他們只是全局對(duì)象的屬性。屬性可以通過(guò)delete刪除,但是變量不行:
// define three globals var global_var = 1; global_novar = 2; // antipattern (function () { global_fromfunc = 3; // antipattern }()); // attempt to delete delete global_var; // false delete global_novar; // true delete global_fromfunc; // true // test the deletion typeof global_var; // "number" typeof global_novar; // "undefined" typeof global_fromfunc; // "undefined"
在ES5的嚴(yán)格模式下,給一個(gè)為聲明的變量賦值會(huì)報(bào)錯(cuò)。
讀取全局對(duì)象
在瀏覽器中,你可以通過(guò)window變量來(lái)讀取全局對(duì)象(除非你在函數(shù)內(nèi)部重新定義了window對(duì)象)。但在有的環(huán)境中,可能不叫window,那么你可以使用下面的代碼來(lái)獲取全局對(duì)象:
var global = (function(){ return this; })();
這樣可以獲取到全局對(duì)象的原因是在function的內(nèi)部,this指向全局對(duì)象。但是這在ES5的嚴(yán)格模式下會(huì)不起作用,你需要適配一些其他模式。當(dāng)你開(kāi)發(fā)自己的庫(kù)的時(shí)候,你可以把你的代碼封裝在一個(gè)立即函數(shù)中,然后將this作為一個(gè)參數(shù)傳進(jìn)來(lái)。
單個(gè)var模式
在你的代碼的頂部只是用一個(gè)var關(guān)鍵字,會(huì)有以下的好處:
- 對(duì)于所有需要的變量,在一個(gè)地方就可以全部看到
- 避免使用一個(gè)未定義的變量
- 幫助你記憶聲明的變量,減少全局變量
- 更精簡(jiǎn)的代碼
書(shū)寫(xiě)很簡(jiǎn)單:
function func() { var a = 1, b = 2, sum = a + b, myobject = {}, i, j; // function body... }
通過(guò)一個(gè)var和逗號(hào)來(lái)聲明多個(gè)變量。在聲明的時(shí)候給變量賦默認(rèn)值也是不錯(cuò)的做法,可以避免一些邏輯錯(cuò)誤,提高代碼的可讀性。而后你閱讀的代碼的時(shí)候也可以根據(jù)變量的默認(rèn)值來(lái)方便的猜測(cè)變量的用途。
你也可以在聲明變量的時(shí)候做一些實(shí)際的工作,比如sum = a + b;另外,在操作DOM元素的時(shí)候,你也可以把DOM元素的引用保存在一個(gè)變量中:
function updateElement() { var el = document.getElementById("result"), style = el.style; // do something with el and style... }
濫用了的var
JavaScript允許你在函數(shù)內(nèi)部有多個(gè)var語(yǔ)句,但是卻都表現(xiàn)的如同在函數(shù)的頂部聲明一樣。這個(gè)特性在你使用一個(gè)變量然后在后面又聲明了這個(gè)變量時(shí)會(huì)導(dǎo)致一些奇怪的邏輯問(wèn)題。對(duì)于JavaScript來(lái)說(shuō),只要變量在同一個(gè)作用域,那么就認(rèn)為是聲明了的,就算是在var語(yǔ)句之前使用也一樣?纯催@個(gè)例子:
myname = "global"; // global variable function func() { alert(myname); // "undefined" var myname = "local"; alert(myname); // "local" } func();
在這個(gè)例子中,或許你期望第一次會(huì)彈出global,第二次彈出local。因?yàn)榈谝淮蔚臅r(shí)候沒(méi)有還沒(méi)有使用var聲明myname,這是應(yīng)該是全局變量的myname,第二次聲明了,然后alert之后應(yīng)該是local的值。而事實(shí)上不是這樣的,只要你在函數(shù)中出現(xiàn)了var myname,那么js就認(rèn)為你在這個(gè)函數(shù)中聲明了這個(gè)變量,但是在讀取這個(gè)變量的值的時(shí)候,因?yàn)関ar語(yǔ)句還沒(méi)有執(zhí)行,所以是undefined,很奇怪的邏輯吧。上面的代碼相當(dāng)于:
myname = "global"; // global variable function func() { var myname; // same as -> var myname = undefined; alert(myname); // "undefined" myname = "local"; alert(myname); // "local" } func();
我們來(lái)解釋一下這個(gè)現(xiàn)象,在代碼的解析中,分兩個(gè)步驟,第一步先處理變量函數(shù)的聲明,這一步處理整個(gè)代碼的上下文。第二步就是代碼的運(yùn)行時(shí),創(chuàng)建函數(shù)表達(dá)式以及未定義的變量。實(shí)際上,我們只是假設(shè)了這個(gè)概念,這并不在ECMAScript的規(guī)范中,但是這個(gè)行為常常就是這樣解釋的。
出處:rockux
責(zé)任編輯:bluehearts
上一頁(yè) 如何編寫(xiě)高質(zhì)量的Javascript代碼 [2] 下一頁(yè) 如何編寫(xiě)高質(zhì)量的Javascript代碼 [4]
◎進(jìn)入論壇網(wǎng)頁(yè)制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|