身為開發人員(WEB前端JavaScript開發),不規範的開發不僅使日後程式碼維護變的困難,同時也不利於團隊的合作,通常還會帶來程式碼安全性以及執行效率上的問題。本人在開發工作上就曾與不按規範來開發的同事合作過,與他合作就不能用"愉快"來形容了。現在本人撰寫此文的目的除了與大家分享一點點經驗外,更多的是希望對未來的合作夥伴能夠起到一定的借鑒作用。當然,如果我說的有不科學的地方還希望各路前輩多多指教。以下分條目列出各種規範要求,這些要求都是針對同事編碼毛病提出來的,好些行業約定的其它規範可能不會再提及。
1. 保證代碼壓縮後不出錯
對於大型的JavaScript項目,一般會在產品發佈時對項目包含的所有JavaScript文件進行壓縮處理,比如可以利用Google Closure Compiler Service對代碼進行壓縮,新版jQuery已改用此工具對程式碼進行壓縮,這一般會去掉開發時寫的註釋,除去所有空格和換行,甚至可以把原來較長的變數名替換成短且無意義的變數名,這樣做的目的是加快檔案的下載速度,同時也減少網站存取帶來的額外資料流量,另外在程式碼保護上也起到了一點點作用,至少壓縮後的程式碼即使被還原還是沒那麼容易一下讀懂的。要想程式碼能正確通過壓縮,一般要求語句都要以分號正常結束,大括號也要嚴格結束等,具體還要看壓縮工具的要求。所以如果一開始沒有照標準來做,等壓縮出錯後再回去找錯誤那是浪費時間。
2. 保證程式碼能通過特定IDE的自動格式化功能
一般較為完善的開發工具(例如Aptana Studio)都有程式碼"自動格式"化功能,這項功能有助於實現統一換行、縮排、空格等程式碼編排,你可以設定自己喜歡的格式標準,例如左大括號{是否另起一行。達到這個要求的目的在於方便你的開發團隊成員拿你程式碼的一個副本用IDE自動格式化成他喜歡或熟悉的風格進行閱讀。你同事需要閱讀你的程式碼,可能是因為你寫的是通用方法,他在其它模組開發過程中也要使用到,閱讀你的程式碼能最深入了解方法呼叫和實現的細節,這是簡單API文檔不能達到的效果。
3. 使用標準的文檔註釋
這一要求算是最基本的,這有利於在方法調用處看到方法的具體傳參提示,也可以利用配套文檔工俱生成html或其它格式的開發文檔供其他團隊成員閱讀,你可以嘗試使用jsdoc-toolkit。如果你自動產生的API是出自一個開放平台,就像facebook.com應用,那麼你的文件就是給天下所有開發者看的。另外寫完整註釋,也更方便團隊成員閱讀你的程式碼,透過你的參數描述,團隊成員可以輕鬆知道你所寫的方法傳參與實作細節。當然也方便日後程式碼維護,這樣即使再大的項目,過了很久後,回去改點東西也就不至於自己都忘記了當時自己寫的程式碼是怎麼一回事了。
4. 使用規範有意義的變數名稱
使用規範有意義的變數名稱可以提高程式碼的可讀性,作為大專案開發成員,自己寫的程式碼不僅要讓別人容易看懂。開發大項目,其實每個人寫的代碼量可能都比較大,規範命名,日後自己看回自己的代碼也顯的清晰易懂,比如日後系統升級或新增功能,修改起代碼來也輕鬆多了。如果到頭發現自己當初寫的程式碼現在看不太懂了,那還真是天大的笑話了。
當然,使用有意義的變數名稱也盡量使用標準的命名,例如像這裡:var me = this也許沒有var self = this好,因為self是Python中的關鍵字,在Python中self就是通常語言this的用法。再看下面一個例子,加s顯然比沒有加來的科學些,這樣可以知道這個變數名存的是複數,可能是數組等:
var li = document.getElementsByTagName('li') var lis = document.getElementsByTagName('li')
5. 不使用生偏語法
JavaScript作為一門動態腳本語言,靈活性既是優點也是缺點,眾所周知,動態語言不同層次開發人員對實現同樣一個功能寫出來的程式碼在規範或語法上會存在較大的差異。不管怎麼樣,規範編碼少搞怪,不把簡單問題複雜化,不違反程式碼易讀原則才是大家該做的。
像這語句:typeof(b) == 'string' && alert(b)應該改為:if (typeof(b) == 'string') alert(b),像前面那種用法,利用了&&運算子解析機制:如果偵測到&&前語句回傳false就不再偵測後面語句,在程式碼最佳化方面也有提到把最可能出現的情況先判斷,像這種寫法如果條件少還好,如果條件較多而且語句也長,那程式碼可讀性就相當差。
又例如:+function(a){var p = a;}( 'a')應該改為:(function(a){var p = a;})( 'a'),其實function前面的+號與包含function的()括號作用是一樣的,都是起運算優先作用,後者是常見且容易看明白的防止變數污染的做法,例如好些流行JavaScript框架就是採用後面這種方式。
再說個降低程式碼可讀性的例子,如:function getPostionTxt(type){return type == 2 ? "野外" : (type == 3 ? "商城" : (type == 4 ? "副本" : null));}應該改成:function getPostionTxt(type){var typeData={"2":"野外","3":"商城","4":"複製"};if (typeData[type] ) return typeData[type]; else return null;}。如果type是從0開始不間斷的整數,那麼直接使用陣列還比較簡單,這種結果看起來就清晰多了,看到前面那種多層三元表達式嵌套頭不暈嗎。
6. 不在語句非賦值地方出生中文
語句中不應該出現中文我想一般人都知道,雖然這樣做不影響程序運行,但是顯然有背行業標準要求,當然我們也不是在使用"易語言"做開發。關於這一個問題,我本來不想把它拿出來說的,但我確實遇到有人這樣做的,也不知道是不是因為他的英語實在太爛了,至少還可以用拼音吧,另外尋求翻譯工具幫忙也不錯的選擇。我舉例如下,像以下寫法出現在教學中倒還可以理解:
this.user['名字'] = '張三' 或者this.user.名字= '張三'
7. 明確定義函數固定數量的參數
固定數量參數的函數內部不使用arguments去獲取參數,因為這樣,你定義的方法如果包含較多的腳本,就不能一眼看到這個方法接受些什麼參數以及參數的個數是多少。例如像下面:
var $ = function(){return document.getElementById(arguments[0]);}应该改成:var $ = function(elemID){return document.getElementById(elemID);}
8. 不必熱衷動態事件綁定
雖然知道事件可以動態綁定,例如使用addEventListener或使用jQuery的bind方法,也知道採用動態事件綁定可以讓XHTML更乾淨,但是一般情況下我還是建議直接把事件寫在DOM節點上,我認為這樣可以使程式碼變得更容易維護,因為這樣做,我們在查看原始程式碼的時候就可以輕鬆地知道什麼Element綁定了什麼方法,簡單說這樣比較容易知道一個按鈕或連結點擊時調了什麼方法腳本。
9. 降低程式碼與XHTML的耦合性
不要過於依賴DOM的一些內容特徵來調用不同的腳本程式碼,而應該定義不同功能的方法,然後在DOM上調用,這樣不管DOM是按鈕還是鏈接,方法的調用都是一樣的,比如像下面的實現顯然會存在問題:
function myBtnClick(obj) { if (/确定/.test(obj.innerHTML)) alert('OK'); else if (/取消/.test(obj.innerHTML)) alert('Cancel'); else alert('Other'); } <a herf="javascript:;" onclick="myBtnClick(this)">确定</a><a herf="javascript:;" onclick="myBtnClick(this)">取消</a>
上面例子其實在一個函數內處理了兩件事情,應該分成兩個函數,像上面的寫法,如果把鏈接換成按鈕,例如改成這樣:,那麼myBtnClick函數內部的obj.innerHTML就出問題了,因為此時應該obj .value才對,另外如果把按鈕名稱由中文改為英文也會出問題,所以這種做法問題太多了。
10. 一个函数应该返回统一的数据类型
因为JavaScrip是弱类型的,在编写函数的时候有些人对于返回类型的处理显得比较随便,我觉得应该像强类型语言那样返回,看看下面的两个例子:
function getUserName(userID) { if (data[userID]) return data[userID]; else return false; } 应该改为: function getUserName(userID) { if (data[userID]) return data[userID]; else return ""; }
这个方法如果在C#中定义,我们知道它准备返回的数据类型应该是字符串,所以如果没有找到这个数据我们就应该返回空的字符串,而不是返回布尔值或其它不合适的类型。这并没有影响到函数将来的调用,因为返回的空字符串在逻辑判断上可被认作"非",即与false一样,除非我们使用全等于"==="或typeof进行判断。
11. 规范定义JSON对象,补全双引号
使用标准肯定是有好处的,那么为什么还是有人不使用标准呢?我想这可能是懒或习惯问题。也许还会有人跟我说,少写引号可以减轻文件体积,我认为这有道理但不是重点。对于服务器返回的JSON数据,使用标准结构可以利用Firefox浏览器的JSONView插件方便查看(像查看XML那样树形显示),另外你如果使用jQuery做开发,最新版本jQuery1.4+是对JSON格式有更高要求的,具体的可以自己查阅jQuery更新文档。比如:{name:"Tom"}或{'name':'Tom'}都应该改成{"name":"Tom"}。
12. 不在文件中留下未来确定不再使用的代码片段
当代码调整或重构后,之前编写的不再使用的代码应该及时删除,如果认为这些代码还有一定利用价值可以把它们剪切到临时文件中。留在项目中不仅增加了文件体积,这对团队其它成员甚至自己都起到一定干扰作用,怕将来自己看回代码都搞不懂这方法是干什么的,是否有使用过。当然可以用文档注释标签@deprecated把这个方法标识为不推荐的。
13. 不重复定义其他团队成员已经实现的方法
对于大型项目,一般会有部分开发成员实现一些通用方法,而另外一些开发成员则要去熟悉这些通用方法,然后在自己编写模块遇到有调用的需要就直接调用,而不是像有些开发者喜欢"单干",根本不会阅读这些通用方法文档,在自己代码中又写了一遍实现,这不仅产生多余的代码量,当然也是会影响团队开发效率的,这是没有团队合作精神的表现,是重复造轮子的悲剧。
比如在通用类文件Common.js有定义function $(elemID){return document.getElementById(elemID)}那么就不应该在Mail.js中再次出现这一功能函数的重复定义,对于一些复杂的方法更应该如此。
14. 调用合适的方法
当有几个方法都可以实现同类功能的时候,我们还是要根据场景选择使用最合适的方法。下面拿jQuery框架的两个AJAX方法来说明。如果确定服务器返回的数据是JSON应该直接使用$.getJSON,而不是使用$.get得到数据再用eval函数转成JSON对象。如果因为本次请求要传输大量的数据而不得以使用$.post也应该采用指定返回数据类型(设置dataType参数)的做法。如果使用$.getJSON,在代码中我们一眼能看出本次请求服务器返回的是JSON。
温馨提示:jQuery1.4后,如果服务器有设置数据输出的ContentType,比如ASP.NET C#设置 Response.ContentType = "application/json",那么$.get将与$.getJSON的使用没有什么区别。
15. 使用合适的控件存储合适的数据
曾發現有人利用DIV來保存JSON數據,以待頁面下載後將來使用,像這樣:
其實也可以利用window物件來保存一些數據,像上面的例子,我們可以在AJAX請求頁直接包含這樣的腳本區塊:<script>window.userData = { "name":"Tom"};</ script>,當在AJAX請求回呼函數中執行完$( "#MyDiv ").html(data)後,在window上就馬上有了這個變數。如果採用第一種方法,將不可避免eval(document.getElementById("UserData").innerHTML)。如果在window物件存放大量資料的話,這些資料不用時要及時手動清理它們,它們是要等瀏覽器刷新或重啟後才會消失的,這就會增加記憶體開銷。 </script>
16. 永遠不要忽略程式碼最佳化工作
程式碼最優化是每個程式設計師應該努力達到的目標,也應該成為程式設計師永遠的追求。寫程式碼的時候,不應該急著把功能實現出來,要想如何寫程式碼,程式碼的執行效率才是較好的。
舉個例子:假設有定義getElementById的快捷方法functoin $(elemID){return document.getElementById(elemID)},那麼有人可能會寫出這樣的程式碼$("MyDiv").parentNode.removeChild($( "MyDiv")),其實這裡執行了兩次getElementById DOM查找,如果改成這樣會更好:var myDiv = $("MyDiv"); myDiv.parentNode.removeChild(myDiv)。還好getElementById的DOM查找算比較快,如果換成getElementsByTagName則更該注重優化了。 jQuery開發團隊也有提醒大家要注意這方面的問題。
當然,程式碼最佳化技巧也是需要個人不斷累積的。曾有朋友跟我說他寫網站後台程式碼從來不用考慮優化的,因為他們網站用的是至強四核心伺服器,我覺得這是很可笑的。
17. 會分析規劃文檔,能用物件導向方法進行介面定義和程式碼組織
這一能力對於每一個程式設計師來說都是非常重要的,這也是決定一個程式設計師水準高低的一個重要因素。能夠把需求細化並抽像出不同的類,然後有條理地編寫程式碼,使程式碼結構清晰,可讀性高,程式碼易於維護,不至於太過程化而且雜亂無章,這樣才算是一個優秀的程式設計師。
以上就是如何寫出規範的JavaScript程式碼 的內容,更多相關內容請關注PHP中文網(www.php.cn)!