轉 http://code.google.com/p/grace/wiki/DojoStyle
前言
相當不錯的 Javascript 編程風格規范,建議大家采用此規范編寫 Javascript。原文鏈接: http://dojotoolkit.org/developer/StyleGuide 。
翻譯(Translated by):i.feelinglucky{at}gmail.com from http://www.gracecode.com ,轉載請注明出處、作者和翻譯者,謝謝配合。
本文地址: http://code.google.com/p/grace/wiki/DojoStyle 。
序
Any violation to this guide is allowed if it enhances readability.
快讀參考
結構 | 規則 | 注釋 |
模塊 | 小寫 | 不要使用多重語義(Never multiple words) |
類 | 駱駝 | |
公有方法 | 混合 | 其他的外部調用也可以使用 lower_case(),這樣的風格 |
公有變量 | 混合 | |
常量 | 駱駝 或 大寫 |
結構 | 規則 |
私有方法 | 混合,例子:_mixedCase |
私有變量 | 混合,例子:_mixedCase |
方法(method)參數 | 混合,例子:_mixedCase, mixedCase |
本地(local)變量 | 混合,例子:_mixedCase, mixedCase |
命名規范
- 變量名稱 必須為 小寫字母。
- 類的命名使用駱駝命名規則,例如:
- 常量 必須 在對象(類)或者枚舉變量的前部聲明。枚舉變量的命名必須要有實際的意義,并且其成員 必須 使用駱駝命名規則或使用大寫:
- 簡寫單詞 不能使用 大寫名稱作為變量名:
- 方法的命令 必須 為動詞或者是動詞短語:
- 公有類的命名 必須 使用混合名稱(mixedCase)命名。
- CSS 變量的命名 必須 使用其對應的相同的公共類變量。
- 私有類的變量屬性成員 必須 使用混合名稱(mixedCase)命名,并前面下下劃線(_)。例如:
- 變量如果設置為私有,則前面 必須 添加下劃線。
- 通用的變量 必須 使用與其名字一致的類型名稱:
- 所有的變量名 必須 使用英文名稱。
- 變量如有較廣的作用域(large scope),必須使用全局變量;此時可以設計成一個類的成員。相對的如作用域較小或為私有變量則使用簡潔的單詞命名。
- 如果變量有其隱含的返回值,則避免使用其相似的方法:
- 公有變量必須清楚的表達其自身的屬性,避免字義含糊不清,例如:
- 類/構造函數 可以使用 擴展其基類的名稱命名,這樣可以正確、迅速的找到其基類的名稱:
Account, EventHandler
var NodeTypes = {
Element : 1,
DOCUMENT: 2
}
getInnerHtml(), getXml(), XmlDocument
obj.getSomeValue()
var MyClass = function(){
var _buffer;
this.doSomething = function(){
};
}
this._somePrivateVariable = statement;
setTopic(topic) // 變量 topic 為 Topic 類型的變量
getHandler(); // 避免使用 getEventHandler()
MouseEventHandler,而非 MseEvtHdlr。
請再次注意這條規定,這樣做得的好處是非常明顯的。它能明確的表達表達式所定義的含義。例如:dojo.events.mouse.Handler // 而非 dojo.events.mouse.MouseEventHandler
EventHandler
UIEventHandler
MouseEventHandler
基類可以在明確描述其屬性的前提下,縮減其命名:MouseEventHandler as opposed to MouseUIEventHandler.
特殊命名規范
- 術語 "get/set" 不要和一個字段相連,除非它被定義為私有變量。
- 前面加 "is" 的變量名 應該 為布爾值,同理可以為 "has", "can" 或者 "should"。
- 術語 "compute" 作為變量名應為已經計算完成的變量。
- 術語 "find" 作為變量名應為已經查找完成的變量。
- 術語 "initialize" 或者 "init" 作為變量名應為已經實例化(初始化)完成的類或者其他類型的變量。
- UI (用戶界面)控制變量應在名稱后加控制類型,例如: leftComboBox, TopScrollPane。
- 復數必須有其公共的名稱約定(原文:Plural form MUST be used to name collections)。
- 帶有 "num" 或者 "count" 開頭的變量名約定為數字(對象)。
- 重復變量建議使用 "i", "j", "k" (依次類推)等名稱的變量。
- 補充用語必須使用補充詞,例如: get/set, add/remove, create/destroy, start/stop, insert/delete, begin/end, etc.
- 能縮寫的名稱盡量使用縮寫。
- 避免產生歧義的布爾變量名稱,例如:
- 錯誤類建議在變量名稱后加上 "Exception" 或者 "Error"。
- 方法如果返回一個類,則應該在名稱上說明返回什么;如果是一個過程,則應該說明做了什么。
isNotError, isNotFound 為非法
文件
- 代碼折疊必須看起來是完成并且是合乎邏輯的:
var someExpression = Expression1
+ Expression2
+ Expression3;
var o = someObject.get(
Expression1,
Expression2,
Expression3
);
注:表達式的縮進與變量聲明應為一致的。
注:函數的參數應采用明確的縮進,縮進規則與其他塊保持一致。
變量
- 變量必須在聲明初始化以后才能使用,即便是 NULL 類型。
- 變量不能產生歧義。
- 相關的變量集應該放在同一代碼塊中,非相關的變量集不應該放在同一代碼塊中。
- 變量應該盡量保持最小的生存周期。
- 循環/重復變量的規范:
- 只有循環控制塊的話,則必須使用 FOR 循環。
- 循環變量應該在循環開始前就被初始化;如使用 FOR 循環,則使用 FOR 語句初始化循環變量。
- "do ... while" 語句是被允許的。
- "break" 和 "continue" 語句仍然允許使用(但請注意)。
- 條件表達式
- 應該盡量避免復雜的條件表達式,如有必要可以使用臨時布爾變量。
- The nominal case SHOULD be put in the "if" part and the exception in the "else" part of an "if" statement.
- 應避免在條件表達式中加入塊。
- 雜項
布局
塊
- 普通代碼段 應該 看起來如下:
- IF 語句 應該 看起來像這樣:
- FOR 語句 應該 看起來像這樣:
- WHILE 語句 應該 看起來像這樣:
- DO ... WHILE 語句 應該 看起來像這樣:
- SWITCH 語句 應該 看起來像這樣:
- TRY ... CATCH 語句 應該 看起來像這樣:
- 單行的 IF - ELSE,WHILE 或者 FOR 語句也 必須 加入括號,不過他們可以這樣寫:
while (!isDone){
doSomething();
isDone = moreToDo();
}
if (someCondition){
statements;
} else if (someOtherCondition){
statements;
} else {
statements;
}
for (initialization; condition; update){
statements;
}
while (!isDone) {
doSomething();
isDone = moreToDo();
}
do {
statements;
} while (condition);
switch (condition) {
case ABC:
statements;
// fallthrough
case DEF:
statements;
break;
default:
statements;
break;
}
try {
statements;
} catch(ex) {
statements;
} finally {
statements;
}
if (condition){ statement; }
while (condition){ statement; }
for (intialization; condition; update){ statement; }
空白
- 操作符 建議 使用空格隔開(包括三元操作符)。
- 下面的關鍵字 避免使用 空白隔開:
- break
- catch
- continue
- do
- else
- finally
- for
- function (如果為匿名函數,例如:var foo = function(){}; )
- if
- return
- switch
- this
- try
- void
- while
- with
- 下面的關鍵字必須使用空白隔開:
- 逗號(,) 建議 使用空白隔開。
- 冒號(:) 建議 使用空白隔開。
- 點(.) 在后部 建議 使用空白隔開。
- 點(.) 避免 在前部使用空白。
- 函數調用和方法 避免 使用空白,例如: doSomething(someParameter); // 而非 doSomething (someParameter)
- 邏輯塊 之間使用空行。
- 聲明 建議 對齊使其更容易閱讀。
注釋
- 生澀的代碼就 沒有必要 添加注釋了,首先您需要 重寫 它們。
- 所有的注釋請使用英文。
- 從已解決的方案到未開發的功能,注釋 必須 與代碼相關。
- 大量的變量申明后 必須 跟隨一段注釋。
- 注釋需要說明的是代碼段的用處,尤其是接下來的代碼段。
- 注釋 沒有必要 每行都添加。
文檔
基本函數信息
function(){
// summary: Soon we will have enough treasure to rule all of New Jersey.
// description: Or we could just get a new roomate.
// Look, you go find him. He don't yell at you.
// All I ever try to do is make him smile and sing around
// him and dance around him and he just lays into me.
// He told me to get in the freezer 'cause there was a carnival in there.
// returns: Look, a Bananarama tape!
}
對象函數信息
{
// summary: Dingle, engage the rainbow machine!
// description:
// Tell you what, I wish I was--oh my g--that beam,
// coming up like that, the speed, you might wanna adjust that.
// It really did a number on my back, there. I mean, and I don't
// wanna say whiplash, just yet, cause that's a little too far,
// but, you're insured, right?
}
函數的聲明
在有的情況下,對于函數的調用和聲明是隱義(invisible)的。在這種情況下,我們沒有辦法在函數中加入說明等(供程序調用)。如果您遭遇了這種情況,您可以使用一個類來封裝函數。
注:此此方法只能在函數沒有初始化的參數情況下。如過不是,則它們會被忽略。
dojo.declare(
"foo",
null,
{
// summary: Phew, this sure is relaxing, Frylock.
// description:
// Thousands of years ago, before the dawn of
// man as we knew him, there was Sir Santa of Claus: an
// ape-like creature making crude and pointless toys out
// of dino-bones, hurling them at chimp-like creatures with
// crinkled hands regardless of how they behaved the
// previous year.
// returns: Unless Carl pays tribute to the Elfin Elders in space.
}
);
參數
- 簡單類型
- 可變類型參數
- 全局參數描述
簡單的類型的參數可以直接在函數參數定義中注釋說明。function(/*String*/ foo, /*int*/ bar)...
下面是幾個修飾符供參考:
function(/*String?*/ foo, /*int...*/ bar, /*String[]*/ baz)...
如果你想增加一個描述,你可以將它們移至初始化塊。
基本信息格式為: *關鍵字* 描述字段 ( *key* Descriptive sentence)
參數和變量的格式為: *關鍵字* ~*類型*~ 描述字段 ( *key* ~*type*~ Descriptive sentence)
注: *關鍵字* 和 ~*類型*~ 可以使用任何字母和數字表述。function (foo, bar) {
// foo: String
// used for being the first parameter
// bar: int
// used for being the second parameter
}
變量
由于實例變量、原型變量和外部變量的聲明是一致的,所以有很多的方法聲明、修改變量。具體的如何定義和定位應在變量最先出現的位置指明變量的名稱、類型、作用域等信息。
function foo() {
// myString: String
// times: int
// How many times to print myString
// separator: String
// What to print out in between myString*
this.myString = "placeholder text";
this.times = 5;
}
foo.prototype.setString = function (myString) {
this.myString = myString;
}
foo.prototype.toString = function() {
for(int i = 0; i < this.times; i++) {
dojo.debug(this.myString);
dojo.debug(foo.separator);
}
}
foo.separator = "=====";
對象中的變量注釋
{
// key: String
// A simple value
key: "value",
// key2: String
// Another simple value
}
返回值
function() {
if (arguments.length) {
return "You passed argument(s)"; // String
} else {
return false; // Boolean
}
}
偽代碼(有待討論)
這樣看起來在 /*===== 和 =====*/ 會有非常長的一段注釋,等待功能調整完畢以后就可以考慮是否刪除。
/*=====
module.pseudo.kwArgs = {
// url: String
// The location of the file
url: "",
// mimeType: String
// text/html, text/xml, etc
mimeType: ""
}
=====*/
function(/*module.pseudo.kwArgs*/ kwArgs){
dojo.debug(kwArgs.url);
dojo.debug(kwArgs.mimeType);
}