前端工程程式碼規範(四)——JS

micherwa發表於2018-05-26

縮排與分號

  • 使用soft tab(4個空格)。
  • 每條語句結尾都需要有分號。
/* 變數申明 */
var x = 1;

/* 表示式 */
x++;

/* do-while */
do {
    x++;
} while (x < 10);

空格

不需要空格的情況:

  • 物件的屬性名後
  • 字首一元運算子後,字尾一元運算子前
  • 函式呼叫括號前
  • 無論是函式宣告還是函式表示式,'('前不要空格
  • 陣列的'['後和']'前,物件的'{'後和'}'前,運算子'('後和')'前
// 一元運算子 和 三元運算子
++x;
y++;
z = x ? 1 : 2;

// 物件的屬性
var a = {
    b: 1
};

// 陣列
var a = [1, 2];

// 運算子
var a = (1 + 2) * 3;

需要空格的情況:

  • 二元運算子前後(加減乘除等)
  • 三元運算子'?:'前後
  • 程式碼塊'{'前
  • 下列關鍵字前:else, while, catch, finally
  • 下列關鍵字後:if, else, for, while, do, switch, case, try,catch, finally, with, return, typeof
  • 單行註釋'//'後(若單行註釋和程式碼同行,則'//'前也需要)多行註釋'*'後物件的屬性值前
  • for迴圈,分號後留有一個空格,前置條件如果有多個,逗號後留一個空格
  • 無論是函式宣告還是函式表示式,'{'前一定要有空格
  • 函式的引數之間
var doSomething = function(a, b, c) {
    // do something
};

//  '('前無空格
doSomething(item);

// 迴圈
for (i = 0; i < 6; i++) {
    x++;
}

空行

  • 變數宣告後(當變數宣告在程式碼塊的最後一行時,則無需空行)
  • 註釋前(當註釋在程式碼塊的第一行時,則無需空行)
  • 程式碼塊後(在函式呼叫、陣列、物件中則無需空行)
  • 檔案最後保留一個空行
// 變數申明後,需要空行
var x = 1;

// 當變數申明位於最後一行時,無需空行
if (x >= 1) {
    var y = x + 1;
}

var a = 2;

// 需要在此註釋之前空行
a++;

function b() {
    // 當註釋位於程式碼塊首行時,無需空行
    return a;
}

// 程式碼塊之後需要空行
for (var i = 0; i < 2; i++) {
    if (true) {
        return false;
    }

    continue;
}

var obj = {
    foo: function() {
        return 1;
    },

    bar: function() {
        return 2;
    }
};

換行

換行的地方,行末必須有','或者運算子。

需要換行的情況:

  • 程式碼塊'{'後和'}'前
  • 變數賦值後
  • 判斷語句中的條件過多過長

不需要換行的情況:

  • 下列關鍵字後:else, catch, finally
  • 程式碼塊'{'前
var a = {
    b: 1,
    c: 2
};

if (condition) {
    ...
} else {
    ...
}

try {
    ...
} catch (e) {
    ...
} finally {
    ...
}

function test() {
    ...
}

var a,
    foo = 7,
    b, c, bar = 8;
    
// 判斷語句中的條件過多過長
if (boolean1 &&
    boolean2 &&
    boolean3) {
    // do someting
}

註釋

單行註釋

  • 雙斜線後,必須跟一個空格;
  • 縮排與下一行程式碼保持一致;
  • 不要寫在程式碼行之後。
if (condition) {
    // 縮排與下一行程式碼保持一致
    allowed();
}

多行註釋

  • 最少三行, '*'後跟一個空格,具體參照右邊的寫法;
  • 適合的場景:難於理解的程式碼段、可能存在錯誤的程式碼段、瀏覽器特殊的HACK程式碼、業務邏輯強相關的程式碼
/*
 * one space after '*'
 */
var x = 1;

文件註釋
參考jsdoc,多用於註釋函式與類。

/**
 * @func
 * @desc 一個帶引數的函式
 * @param {string} a - 引數a
 * @param {number} b=1 - 引數b預設值為1
 * @param {string} c=1 - 引數c有兩種支援的取值</br>1—表示x</br>2—表示xx
 * @param {object} d - 引數d為一個物件
 * @param {string} d.e - 引數d的e屬性
 * @param {string} d.f - 引數d的f屬性
 * @param {object[]} g - 引數g為一個物件陣列
 * @param {string} g.h - 引數g陣列中一項的h屬性
 * @param {string} g.i - 引數g陣列中一項的i屬性
 * @param {string} [j] - 引數j是一個可選引數
 */
function foo(a, b, c, d, g, j) {
    ...
}

引號

最外層統一使用單引號。

let y = 'foo';
let z = '<div id="test"></div>';

變數命名

  • 標準變數採用駝峰式命名(除了物件的屬性外)
  • 'ID'在變數名中全大寫
  • 'Android'在變數名中大寫第一個字母
  • 'iOS'在變數名中小寫第一個,大寫後兩個字母
  • 常量全大寫,用下劃線連線
  • 建構函式,大寫第一個字母
var thisIsMyName;

var goodID;

var AndroidVersion;

var iOSVersion;

var MAX_COUNT = 10;

function Person(name) {
    this.name = name;
}

函式

  • 無論是函式宣告還是函式表示式,'('前不要空格,但'{'前一定要有空格;
  • 函式呼叫括號前不需要空格;
  • 立即執行函式外必須包一層括號;
  • 不要給inline function命名;
  • 引數之間用', '分隔,注意逗號後有一個空格;
  • 一個函式內,最多3層縮排,專注於實現一件事。
var doSomething = function(item) {
    // do something
};

function doSomething(item) {
    // do something
}

doSomething(item);

// 立即執行函式
(function() {
    return 1;
})();

// inline function
var a = [1, 2, function() {
    ...
}];

// 引數間以', '分割
var doSomething = function(a, b, c) {
    // do something
};

括號

下列關鍵字後必須有大括號(即使程式碼塊的內容只有一行):if, else,for, while, do, switch, try, catch, finally, with。

// not good
if (condition)
    doSomething();

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

null

適用場景:

  • 初始化一個將來可能被賦值為物件的變數
  • 與已經初始化的變數做比較
  • 作為一個引數為物件的函式的呼叫傳參
  • 作為一個返回物件的函式的返回值

不適用場景:

  • 不要用null來判斷函式呼叫時有無傳參
  • 不要與未初始化的變數做比較
// not good
function test(a, b) {
    if (b === null) {
        // not mean b is not supply
        ...
    }
}

// good
var a = null;

if (a === null) {
    ...
}

undefined

永遠不要直接使用undefined進行變數判斷;

使用typeof和字串'undefined'對變數進行判斷。

// not good
if (person === undefined) {
    ...
}

// good
if (typeof person === 'undefined') {
    ...
}

jshint

  • 用'===', '!=='代替'==', '!=';
  • for-in裡一定要有hasOwnProperty的判斷;
  • 不要在內建物件的原型上新增方法,如Array, Date;
  • 不要在內層作用域的程式碼裡宣告瞭變數,之後卻訪問到了外層作用域的同名變數;
  • 變數不要先使用後宣告;
  • 不要在一句程式碼中單單使用建構函式,記得將其賦值給某個變數;
  • 不要在同個作用域下宣告同名變數;
  • 不要在一些不需要的地方加括號,例:delete(a.b);
  • 不要使用未宣告的變數(全域性變數需要加到.jshintrc檔案的globals屬性裡面);
  • 不要宣告瞭變數卻不使用;
  • debugger不要出現在提交的程式碼裡;
  • 陣列中不要存在空元素;
  • 不要在迴圈內部宣告函式;
  • 不要像這樣使用建構函式,例:new function () { ... }, new Object
// not good
if (a == 1) {
    a++;
}

// good
if (a === 1) {
    a++;
}

// good
for (key in obj) {
    if (obj.hasOwnProperty(key)) {
        // be sure that obj[key] belongs to the object and was not inherited
        console.log(obj[key]);
    }
}

// not good
Array.prototype.count = function(value) {
    return 4;
};

// not good
var x = 1;

function test() {
    if (true) {
        var x = 0;
    }

    x += 1;
}

// not good
function test() {
    console.log(x);

    var x = 1;
}

// not good
new Person();

// good
var person = new Person();

// not good
delete(obj.attr);

// good
delete obj.attr;

// not good
if (a = 10) {
    a++;
}

// not good
var a = [1, , , 2, 3];

// not good
var nums = [];

for (var i = 0; i < 10; i++) {
    (function(i) {
        nums[i] = function(j) {
            return i + j;
        };
    }(i));
}

// not good
var singleton = new function() {
    var privateVar;

    this.publicMethod = function() {
        privateVar = 1;
    };

    this.publicMethod2 = function() {
        privateVar = 2;
    };
};

雜項

  • 不要混用tab和space,或在一處使用多個tab或space;
  • 對上下文this的引用只能使用'_this', 'that', 'self'其中一個來命名;
  • 行尾不要有空白字元;
  • switch的falling through和no default的情況一定要有註釋特別說明;
  • 不允許有空的程式碼塊。
function Person() {
    // not good
    var me = this;

    // good
    var _this = this;

    // good
    var that = this;

    // good
    var self = this;
}

目錄索引

前端工程程式碼規範(一)——命名規則與工程約定
前端工程程式碼規範(二)——HTML
前端工程程式碼規範(三)——CSS, SCSS


相關文章