《編寫可維護的javascript》推薦的編碼規範之——編程風格

javaScript編碼規範javascript

 

這正是本書的內容:如何站在團隊的角度去寫javascript代碼。目標是解決多人開發的環境中不少工程師如何書寫統一風格的代碼的問題。對於我的來講,須要在必定程度上犧牲我的偏好、我的觀點甚至我的英雄主義,但你所收穫的將是一個能作大事的高效團隊。java

肯定並一致的遵循約定比這個約定具體是什麼更爲重要。編程

 

java語言編碼規範」指出編碼規範如此重要的幾個緣由:數組

  • 軟件生命週期中80%的成本消耗在了維護上。
  • 幾乎全部的軟件維護者都不是它的最初做者。
  • 編碼規範提升了軟件的可讀性,它讓工程師可以快速且充分的理解新的代碼。
  • 若是你將源碼做爲產品來發布,你須要確保它是可完整打包的,且像你建立的其餘產品同樣整潔。

 

編碼規範包括:安全

  • 編程風格
  • 編程最佳實踐
  • 文件和目錄的規劃以及註釋等方面

 

規範的制定和規範的執行是兩碼事。編輯器

檢查工具:JSLintJSHintJSLint的一個分支項目),推薦使用JSHint .ide

 

1、編程風格函數

 

一、格式規則(formating rule工具

 

1.1 縮進編碼

  • 推薦使用四個空格的縮進。你能夠在編輯器中配置tab鍵插入4個空格
  • 也可使用製表符縮進,但須要知道的是不一樣系統或不一樣編輯器極可能會看到不一樣的縮進。

決不能二者混用!

 

1.2 語句結尾

自動分號插入(Automatic Semicolon InsertionASI)機制雖然在大多數場景下都會正確插入分號,但它的分號插入規則很是複雜,所以推薦不要省略分號。

 

1.3 行的長度

建議將行長度限制在80個字符

 

1.4 換行

建議在運算符後換行,下一行增長兩個層級的縮進,如:

callAFunction( document, elm, 'some string value', 
        true );

這個例子中,逗號是運算符,應看成爲前一行的行尾。老是將一個運算符置於行尾,ASI就不會自做主張地插入分號,也就避免了錯誤的發生。又一例:

if( isLeapYear && isFebruary && day == 29 && itsYourBirthday && 
        noPlans ) {

    waitAnotherFourYears();
}

var result = something + anotherThing + yetAnotherThing + somethingElse +
             anotherSomethingElse; 

 

1.5 空行

一般來說,代碼看起來應當像一系列可讀的段落,而不是一大段揉在一塊兒的連續文本。有時一段代碼的語義和另外一段代碼不相關,這是就應該使用空行將它們分隔,確保語義相關的代碼展示在一塊兒。通常來說,在下面這些場景中添加空行也是不錯的注意。 

  • 方法之間。
  • 方法中的局部變量和第一條語句之間。
  • 註釋以前。
  • 方法內的邏輯片段之間

 

1.6 命名

Javascript語言的核心ECMAscript,便是遵循了駝峯式大小寫(Camel case)命名法

 

1.6.1 變量和函數

變量命名前綴應當是名詞;函數名前綴應當是動詞。如:

var count = 10;

function getName () {
    return name; 
}

命名長度應該儘量短,並抓住要點。儘可能在變量名中體現出值的數據類型。好比,countlength 和 size 代表數據類型是數字;nametitle和 message 代表數據類型是字符串。i和 一般在循環中使用。

一些使用動詞常見的約定:

  • can:函數返回一個布爾值
  • has:函數返回一個布爾值
  •  is:函數返回一個布爾值
  • get:函數返回一個非布爾值
  • set:函數用來保存一個值

當給變量賦值時,若是右側是含有比較語句的表達式,須要用括號包裹:

// 好的寫法
var aflag = (i < count);

// 很差的寫法
var flag = i < count;

另外,三元運算符應當僅僅在條件賦值語句中,而不要做爲if語句的替代品

// 好的寫法
var val = condition ? value1 : value2;

// 很差的寫法
condition ? doSomething(): doSomethingElse();

 

1.6.2 常量

使用大寫字母和下劃線來命名,下劃線用以分隔單詞。如:

var MAX_COUNT = 10;

 

1.6.3 構造函數

構造函數的命名一般是名詞,且採用大駝峯命名法(Pascal Case)

 

 

1.7 直接量

 

1.7.1 字符串

使用單引號仍是雙引號均可以,重要的是你的代碼從頭至尾只保持一種風格。

 

1.7.2 數字

Javascript只有一種數字類型。

  • 不推薦沒有整數部分的小數寫法:var price = .1;
  • 不推薦已經被棄用的八進制寫法:var num = 010;

 

1.7.3 null

null是一個特殊值,但咱們經常誤解它,將它和undefined 搞混。下列場景中應當使用null:

 

  • 用來初始化一個可能賦值爲一個對象的變量。
  • 用來和一個已經初始化的變量作比較,這個變量能夠是也能夠不是一個對象。
  • 當函數的參數指望是對象時,用做作參數傳入。
  • 當函數的返回值指望是對象時,用做返回值傳出。

理解null最好的方式是將它當作對象的佔位符,這一點對於全局可維護性來講相當重要。

 

1.7.4 undefined

undefined,表示這個變量等待被賦值。建議避免在代碼中使用undefined

 

1.7.5 對象直接量

推薦採用 對象直接量 的方式來建立對象。如:

var obj = {

    key1: value1,
    key2: value2,
    func: function() {
    
    },
    keyn: valuen    

};

若是屬性或者方法是私有的,應當如下劃線做爲前綴。 

 

1.7.6 數組直接量

推薦採用 數組直接量 的方式來建立數組。

 

 

 

二、註釋

 

2.1 單行註釋

// 在雙斜槓後敲入一個空格

單行註釋有三種使用方法:

  • 獨佔一行的註釋,用來解釋下一行代碼。這行註釋以前老是有一個空行,且縮進層級與下一行代碼保持一致
  • 在代碼行尾的註釋。代碼結尾到註釋之間至少有一個縮進。代碼和註釋不該當超過單行最大字符數限制,若是超過了,就將這條註釋放置於當前代碼行的上方。
if ( condition ) {    // 行尾註釋,與代碼行尾保持一個縮進的距離

    // 前面空一行; 縮進層級與下一行保持一致
    allowed();
}

 註釋一個代碼塊時在連續多行使用單行註釋是惟一能夠接受的狀況。多行註釋不該當在這種狀況下使用:

// if (condition) {
//    doSomething();
//    thenDoSomethingElse();
//}

 

2.2 多行註釋

推薦java風格的多行註釋。Java風格的註釋至少包含三行:第一行是 /* ,第二是以 開始且和上一行的 保持左對齊,最後一行是 */ 。如:

/*
 * Helper functions for managing events -- not part of the public interface.
 * Props to Dean Edwards' addEvent library for many of the ideas.
 */

 

2.3 什麼時候使用註釋

  • 難於理解的代碼
  • 可能被認爲錯誤的代碼
  • hack

 

2.4 (API)文檔註釋

推薦最流行的一種格式來自於JavaDoc文檔格式:多行註釋以單斜線雙星好 /** 開始,接下來是描述信息,其中使用 符號來表示一個或多個屬性。如:

/**
 * 模板引擎路由函數
 * 若第二個參數類型爲 Object 則執行 render 方法, 不然 compile 方法
 * @name    template
 * @param   {String}            模板ID (可選)
 * @param   {Object, String}    數據或者模板字符串
 * @return  {String, Function}  渲染好的HTML字符串或者渲染方法
 */

 推薦使用文檔生成工具來生成:YUIDoc 或 JSDoc Toolkit

 

2.5 註釋聲明

註釋有時候能夠用來給一段代碼聲明額外的信息。這些聲明的格式以單個單詞打頭並緊跟一個雙引號。可使用的聲明以下。

 

TODO,說明代碼還未完成。應該包含下一步要作的事情。

// TODO:我但願找到一種更快的方式
doSomething();

 

HACk,代表代碼走了一個捷徑。應當包含爲什麼使用hack的緣由。這也可能代表該問題可能會有更好的解決方法。

/*
 * HACK:不得不針對IE作的特殊處理。我計劃後續有時間時
 * 重寫這部分。這些代碼可能須要在 v1.2 版本以前替換掉。
 */
if (document.all) {
    dosomething();
}

 

XXX,說明代碼是有問題的並應當儘快修復。

 

FIXME,說明代碼是有問題的並應該儘快修復。重要性略次於XXX。

 

REVIEW,說明代碼任何可能的改動都須要評審。

// REVIEW:有更好的方法嗎?
if (document.all) {
    doSomething();
}

 

以上這些聲明可能在一行或多行註釋中使用,而且應當遵循同通常註釋類型相同的格式規則。

 

 

 

三、語句和表達式

全部的塊語句,不管包含多行仍是單行代碼,都應當老是使用花括號。這包括:

  • if
  • for
  • while
  • do...while...
  • try...catch...finally

 

3.1 花括號對齊方式

建議將左花括號放置在塊語句中第一行代碼的末尾,好比:

if ( condition ) {
    doSomething();
} else {
    doSomethingElse();
}

 

3.2 塊語句間隔

有三種風格:

// Dojo 編程風格指南推薦
if(condition){    
    doSomething();
}

// Google Javascript 風格指南推薦
if (condition) {
    doSometing();
}

// jQuery 核心編碼風格指南推薦
if ( condition ) {
    doSomething();
}

任選一種,保持一致。

 

3.3 switch 語句

case 語句的「連續執行」(也稱穿越),即省略case末尾的break ,使得程序執行完一個case後繼續執行下一個case。這是一個備受爭議的問題。Douglas Crockford認爲會這會致使bug的產生,但jQueryDojo編程風格指南則容許使用。看着辦吧~

switch中還有一個須要討論的議題是,是否須要default。做者的建議是,若是default什麼也沒有作,就把它省略掉。

 

3.4 with語句

強烈推薦避免使用該語句。

 

3.5 for 循環

有兩種方法能夠更改循環的過程,一個是break終止;一個是continue 終止本次,跳到下次。

Crockford的編程規範不容許使用continue。他主張代碼中與其使用continue不如使用條件語句。如:

for ( var i = 0, leng = values.length; i < len; i++ ) {
    if ( i != 2 ) {
        process( values[i] );
    }
}

Crockford解析說這種方法更易於理解且不容易出錯。但Dojo編程風格指南容許使用continue。做者推薦儘量避免使用continue,但也沒有理由徹底禁止使用,它的使用應當根據代碼可讀性來決定。

 

3.5 for-in 循環

建議老是在該循環中使用hasOwnProperty()。不要使用該循環歷遍數組。

 

 

 

四、變量、函數和運算符

 

4.1 變量聲明

由於變量聲明「提早」的緣故,因此建議老是將局部變量的定義做爲函數內第一條語句,並採用單var模式。如:

funtion each (items, callback) {
  var i,
     len,
     value = 10,
     result = value + 10;
  
  for ( i=0, len=items.lengt; i<len; i++ ) {
        callback( items[i] );
    }
}

 

4.2 函數聲明

和變量聲明同樣,函數聲明也會被提早,所以推薦函數內部的局部函數應當緊接着變量聲明以後聲明。

函數聲明不該當出如今語句塊中!

 

4.3 函數調用

推薦的風格是,在函數名和左括號之間沒有空格。這樣作是爲了將它和塊語句區分開來。如:

doSomething(item);
doSomething (item);    // 反例

// 用作對比的塊語句
while (item) {
}

jQuery核心風格指南更進一步,它規定應當在左括號以後和右括號以前都加上空格。如:

doSomething( item );

這種風格是爲了讓參數更易讀。但它也列出了這種風格的一些例外:

doSomething(function() {    });
doSomething({ item: item });
doSomething([ item ]);
doSomething(「Hi!」);

 

4.4 當即函數

爲了讓當即函數可以被一眼看出來,能夠將函數用一對圓括號包裹起來,如:

var value = (function() {
    
}());

 

4.5 嚴格模式

ES5引入了「嚴格模式」(strict mode),推薦儘量使用嚴格模式,但不推薦在全局做用域中使用,應當在局部做用域中使用:

(function() {
    'use strict';

    // 代碼
}());

 

4.6相等

因爲(隱式)強制類型轉換的緣故,不推薦使用 == 和 != ,而應當使用 === 和 !== 。 

二元運算符先後必須使用一個空格來保持表達式的整潔 

 

4.6.1 eval()

一個通用的原則是:

  • 嚴禁使用Function
  • 只在別無他法的時候使用eval()
  • setTimeout()setInterval()不要字符串形式而要用函數

jQuery核心風格指南禁止使用eval(),但有一個惟一的例外,即涉及到回調中解析JSON的情形。Googlejavascript風格指南只容許在將Ajax的返回值轉換爲javascript值的場景下使用eval()

ES5嚴格模式對於eval()有着嚴格的限制,禁止在一個封閉的做用域中使用它建立新的變量或函數。這條限制幫助咱們避免了eval()先天的安全漏洞。

 

4.6.2 原始包裝類型

避免使用StringNumberBoolean建立新對象。

 

 

2、編程實踐

後續...

 

3、自動化

後續...

相關文章
相關標籤/搜索