6.為他人著想(命名空間,作用域和模式)
你的代碼幾乎從來不會是文檔中的唯一的腳本代碼。所以保證你的代碼里沒有其它腳本可以覆蓋的全局函數(shù)或者全局變量就顯得尤為重要。有一些可用的模式可以來避免這個(gè)問題,最基礎(chǔ)的一點(diǎn)就是要使用 var 關(guān)鍵字來初始化所有的變量。假設(shè)我們編寫了下面的腳本:
var nav = document.getElementById('nav'); function init(){ // do stuff } function show(){ // do stuff } function reset(){ // do stuff }
上面的代碼中包含了一個(gè)叫做nav的全局變量和名字分別為 init,show 和 reset 的三個(gè)函數(shù)。這些函數(shù)都可以訪問到nav這個(gè)變量并且可以通過函數(shù)名互相訪問:
var nav = document.getElementById('nav'); function init(){ show(); if(nav.className === 'show'){ reset(); } // do stuff } function show(){ var c = nav.className; // do stuff } function reset(){ // do stuff }
你可以將代碼封裝到一個(gè)對象中來避免上面的那種全局式編碼,這樣就可以將函數(shù)變成對象中的方法,將全局變量變成對象中的屬性。 你需要使用“名字+冒號”的方式來定義方法和屬性,并且需要在每個(gè)屬性或方法后面加上逗號作為分割符。
var myScript = { nav:document.getElementById('nav'), init:function(){ // do stuff }, show:function(){ // do stuff }, reset:function(){ // do stuff } }
所有的方法和屬性都可以通過使用“類名+點(diǎn)操作符”的方式從外部和內(nèi)部訪問到。
var myScript = { nav:document.getElementById('nav'), init:function(){ myScript.show(); if(myScript.nav.className === 'show'){ myScript.reset(); } // do stuff }, show:function(){ var c = myScript.nav.className; // do stuff }, reset:function(){ // do stuff } }
這種模式的缺點(diǎn)就是,你每次從一個(gè)方法中訪問其它方法或?qū)傩远急仨氃谇懊婕由蠈ο蟮拿,而且對象中的所有東西都是可以從外部訪問的。如果你只是想要部分代碼可以被文檔中的其他腳本訪問,可以考慮下面的模塊(module)模式:
var myScript = function(){ //這些都是私有方法和屬性 var nav = document.getElementById('nav'); function init(){ // do stuff } function show(){ // do stuff } function reset(){ // do stuff } //公有的方法和屬性被使用對象語法包裝在return 語句里面 return { public:function(){
}, foo:'bar' } }();
你可以使用和前面的代碼同樣的方式訪問返回的公有的屬性和方法,在本示例中可以這么訪問:myScript.public() 和 myScript.foo 。但是這里還有一點(diǎn)讓人覺得不舒服:當(dāng)你想要從外部或者從內(nèi)部的一個(gè)私有方法中訪問公有方法的時(shí)候,還是要寫一個(gè)冗長的名字(對象的名字可以非常長)。為了避免這一點(diǎn),你需要將它們定義為私有的并且在return語句中只返回一個(gè)別名:
var myScript = function(){ // 這些都是私有方法和屬性 var nav = document.getElementById('nav'); function init(){ // do stuff } function show(){ // do stuff // do stuff } function reset(){ // do stuff } var foo = 'bar'; function public(){
}
//只返回指向那些你想要訪問的私有方法和屬性的指針 return { public:public, foo:foo } }();
這就保證了代碼風(fēng)格一致性,并且你可以使用短一點(diǎn)的別名來訪問其中的方法或?qū)傩浴?/p>
如果你不想對外部暴露任何的方法或?qū)傩,你可以將所有的代碼封裝到一個(gè)匿名方法中,并在它的定義結(jié)束后立刻執(zhí)行它:
(function(){ // these are all private methods and properties var nav = document.getElementById('nav'); function init(){ // do stuff show(); // 這里不需要類名前綴 } function show(){ // do stuff } function reset(){ // do stuff } })();
對于那些只執(zhí)行一次并且對其它函數(shù)沒有依賴的代碼模塊來說,這種模式非常好。
通過遵循上面的那些規(guī)則,你的代碼更好地為用戶工作,也可以使你的代碼在機(jī)器上更好地運(yùn)行并與其他開發(fā)者的代碼和睦相處。不過,還有一個(gè)群體需要考慮到。
7.為接手的開發(fā)者考慮(使維護(hù)更加容易)
使你的腳本真正地unobtrusive的最后一步是在編寫完代碼之后仔細(xì)檢查一遍,并且要照顧到一旦腳本上線之后要接手你的代碼的開發(fā)者。考慮下面的問題:
- 所有的變量和函數(shù)名字是否合理并且易于理解?
- 代碼是否經(jīng)過了合理的組織?從頭到尾都很流暢嗎?
- 所有的依賴都顯而易見嗎?
- 在那些可能引起混淆的地方都添加了注釋嗎?
最重要的一點(diǎn)是:要認(rèn)識到文檔中的HTML和CSS代碼相對于JavaScript來說更有可能被改變(因?yàn)樗鼈冐?fù)責(zé)視覺效果)。所以不要在腳本代碼中包含任何可以讓終端用戶看到的class和ID,而是要將它們分離出來放到一個(gè)保存配置信息的對象中。
myscript = function(){ var config = { navigationID:'nav', visibleClass:'show' }; var nav = document.getElementById(config.navigationID); function init(){ show(); if(nav.className === config.visibleClass){ reset(); }; // do stuff }; function show(){ var c = nav.className; // do stuff }; function reset(){ // do stuff }; }();
這樣維護(hù)者就知道去哪里修改這些屬性,而不需要改動其他代碼。
更多信息
以上就是我發(fā)現(xiàn)的七條準(zhǔn)則。如果你想要了解更多與上面所探討的主題相關(guān)的東西,可以看看下面的鏈接:
本文鏈接:http://www.95time.cn/tech/web/2008/6321.asp
出處:藍(lán)色理想
責(zé)任編輯:bluehearts
上一頁 不唐突的JavaScript的七條準(zhǔn)則 [3] 下一頁
◎進(jìn)入論壇網(wǎng)頁制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評論。
|