js編寫規範

JavaScript編碼規範


Bug----33條

1. 不要使用’==’和’!=’,使用’===’和’!==’替代

  • 等級:Major程序員

  • 緣由:==和!=在判斷值相等前會判斷類型是否相等。這容易由於類型不一樣而形成錯誤。好比:它會認爲表達式:’\t\r\n’==0是正確的。所以,要採用===和!==替代這兩個符號。正則表達式

  • 建議以下的方式:數據庫

    if (var === 'howdy') { ... } 
  • 不建議以下的方式:express

    if (var == 'howdy') { ... } 
  • 例外:在判斷函數是否爲空的狀況下,使用==或!=是能夠的。在下邊的例子中,若是foo沒有被初始化,它默認的值是undefined而不是null。固然underfined更不會等於null了。所以這種狀況應該使用==和!=。編程

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

2. "DELETE"不能在數組中使用

  • 等級:Critical跨域

  • 緣由:delete函數能夠用來刪除任何的對象。數組是對象,所以能夠被delete操做。可是若是這樣使用了,就會在數組中產生一個undefined元素,沒法從下標中反應出delete操做。數組

    從含有下標的元素中移除元素的適當方法有:瀏覽器

    Array.prototype.splice – 從數組中移除元素緩存

    Array.prototype.pop – 從數組的尾端移除元素安全

    Array.prototype.shift – 從數組的開始移除元素

  • 建議以下的方式:

    var myArray = [ 'a', 'b', 'c', 'd' ]; // removes 1 element from index 2 removed = myArray.splice(2, 1); // myArray => ['a', 'b', 'd'] console.log(myArray[2]); // outputs 'd' 
  • 不建議以下的方式:

    var myArray = [ 'a', 'b', 'c', 'd' ]; delete myArray[2]; // Noncompliant. myArray => ['a', 'b', undefined, 'd'] console.log(myArray[2]); // expected value was 'd' but output is 'undefined' 

3. 不能使用"EVAL"和"ARGUMENTS"做爲變量

  • 等級:Critical

  • 緣由:在JavaScript中eval是一個將字符串轉換爲JavaScript代碼執行的函數,而arguments則是JavaScript的一個內置對象。若是二者做爲變量使用就會覆蓋了原先的定義。同是,在較爲嚴格的JavaScript檢測中,這樣作是不會經過的。

  • 建議以下的方式:

    result = 17; args++; ++result; var obj = { set p(arg) { } }; var result; try { } catch (args) { } function x(arg) { } function args() { } var y = function fun() { }; var f = new Function('args', 'return 17;'); function fun() { if (arguments.length == 0) { // do something } } 
  • 不建議以下的方式:

    eval = 17; // Noncompliant arguments++; // Noncompliant ++eval; // Noncompliant var obj = { set p(arguments) { } }; // Noncompliant var eval; // Noncompliant try { } catch (arguments) { } // Noncompliant function x(eval) { } // Noncompliant function arguments() { } // Noncompliant var y = function eval() { }; // Noncompliant var f = new Function('arguments', 'return 17;'); // Noncompliant function fun() { if (arguments.length == 0) { // Compliant // do something } } 

4. "FOR"循環在每次執行時,都要修改控制循環的值

  • 等級:Critical

  • 緣由:若是for循環永遠沒法完成就會產生錯誤。即使不會產生錯誤,也會對之後的變量值形成沒法肯定的影響,所以不可以這樣使用。

  • 建議以下的方式:

    for (i = 0; i < 10; i++) { // ... } 
  • 不建議以下的方式:

    for (i = 0; i < 10; j++) { // Noncompliant // ... } 

5. "FOR … IN"這種循環在每次操做前須要進行過濾判斷

  • 等級:Major

  • 緣由:"for … in"這種循環容許開發人員按照屬性的名字遍歷對象。不幸的是,這個屬性的集合包括了對象自身和對象繼承的對象的全部屬性。若是程序不考慮這點就會出現錯誤。
    所以,對於每一個」for … in」循環,都應該包括一個if判斷來過濾你須要的屬性。

  • 建議以下的方式:

    for (name in object) { if (object.hasOwnProperty(name)) { doSomething(name); } } 
  • 不建議以下的方式:

    for (name in object) { doSomething(name); // Noncompliant } 

6. "INDEXOF"的檢測須要包括0

  • 等級:Major

  • 緣由:大部分字符串或者數組的indexof方法的判斷須要和-1而不是0做比較。由於0表明該元素存在於字符串或者數組中。所以全部的indexof(..)>0的判斷都忽略的0這種狀況,是一個典型的錯誤。

  • 建議以下的方式:

    var color = 'blue'; var name = 'ishmael'; var number = 123; var arr = [color, name]; if (arr.indexOf('blue') >= 0) { // ... } if (arr[0].indexOf('ish') > - 1{ // ... } 
  • 不建議以下的方式:

    var color = 'blue'; var name = 'ishmael'; var number = 123; var arr = [color, name]; if (arr.indexOf('blue') > 0) { // Noncompliant // ... } if (arr[0].indexOf('ish') > 0{ // Noncompliant // ... } 

7. "NAN"不能用在比較中

  • 等級:Blocker

  • 緣由:NAN不等於包括自身在內的任何值。所以與NAN做比較是得不到你須要的結果的,可是這種錯誤有可能會出現。事實上,判斷值是否等於NAN最好的方法就是和它本身做比較即NAN!==NAN,由於正常的變量都是等於自身的,若是不等於自身成立,就說明這個值是NAN。

  • 建議以下的方式:

    if (a !== a) { console.log('a is not a number'); } if (a === a) { console.log('a is not NaN'); } 
  • 不建議以下的方式:

    var a = NaN; if (a === NaN) { // Noncompliant; always false console.log('a is not a number'); // this is dead code } if (a !== NaN) { // Noncompliant; always true console.log('a is not NaN'); // this statement is not necessarily true } 

8. "new"關鍵字應該和構造函數一塊兒使用

  • 等級:Critical

  • 緣由:new這個關鍵字應該在定義了構造函數的對象中使用。若是在其餘地方使用就會出現錯誤由於沒有構造方法能夠供new調用。

  • 建議以下的方式:

    /**
    * @constructor */ function MyClass() { this.foo = 'bar'; } var someClass = function () { this.prop = 1; } var obj1 = new someClass; // Compliant var obj2 = new MyClass(); // Compliant regardless of considerJSDoc value 
  • 不建議以下的方式:

    var someClass = 1; var obj1 = new someClass; // Noncompliant; 

9. 不能使用」WITH」代碼塊

  • 等級:Major

  • 緣由:使用with關鍵字在一些較爲嚴格的JavaScript檢測中會報錯。然而,這並非最糟的,誠然使用with能夠方便的訪問到對象中既定的屬性,可是若是屬性在對象中還沒有定義,則訪問範圍就會擴大到全局,有可能覆蓋某些重名的變量。顯然這種效果徹底依賴於被訪問的對象,而且產生的危害是不可測的,所以with不能使用。

  • 建議以下的方式:

    var x = 'a'; var foo = { y: 1 } foo.y = 4; foo.x = 3; print(foo.x + ' ' + x); // shows: 3 a 
  • 不建議以下的方式:

    var x = 'a'; var foo = { y: 1 } with (foo) { // Noncompliant y = 4; // updates foo.x x = 3; // does NOT add a foo.x property; updates x var in outer scope } print(foo.x + ' ' + x); // shows: undefined 3 

10. "FOR"循環塊裏的控制數值增加的方向必須準確

  • 等級:Blocker

  • 緣由:若是for循環裏的控制變量增加方向錯誤則會致使for循環永遠沒法執行完成。雖然有時候構建無限循環是故意的,好比使用while構建無限循環。可是,大部分狀況下是存在錯誤。

  • 建議以下的方式:

    for (var i = 0; i < strings.length; i++) { //... } 
  • 不建議以下的方式:

    for (var i = 0; i < strings.length; i--) { // Noncompliant; //... } 

11. 不要使用ARRAY和OBJECT的構造方法

  • 等級:Major

  • 緣由:因爲有着對變量的特定解釋方法,數組的構造方法是容易出錯的。若是超過一個參量,數組的長度將會等於參量的數量。然而,若是使用一個參量將會產生三種可能結果:

    若是這個參數是個數字而且是個正整數,則會產生一個長度等於該參數的數組;

    若是這個參數是個數字可是不是個正整數,將會拋出異常;

    其餘狀況下將會產生長度爲1的數組。

  • 建議以下的方式:

    var a = [x1, x2, x3]; var a2 = [x1, x2]; var a3 = [x1]; var a4 = []; var o = {}; var o2 = { a: 0, b: 1, c: 2, 'strange key': 3 }; 
  • 不建議以下的方式:

    var a3 = new Array(x1); // Noncompliant and variable in results var a4 = new Array(); // Noncompliant. Results in 0-element array. var a1 = new Array(x1, x2, x3); // Noncompliant. Results in 3-element array. var o = new Object(); // Noncompliant var o2 = new Object(); // Noncompliant o2.a = 0; o2.b = 1; o2.c = 2; o2['strange key'] = 3; 

12. 子表達式中不要出現賦值語句

  • 等級:Major

  • 緣由:賦值語句在子表達式中容易產生錯誤,而且下降程序的可讀性。像將==寫成=是一種常見的錯誤。

  • 建議以下的方式:

    i = 42; doSomething(i); // or doSomething(i == 42); // Perhaps in fact the comparison operator was expected 
  • 不建議以下的方式:

    doSomething(i = 42); 
  • 例外:賦值語句能夠在while循環或者關係表達式中出現。

    while ((line = nextLine()) != null) { ... } // Compliant while (line = nextLine()) { ... } // Compliant if (line = nextLine()) { ... } // Noncompliant 

13. 內置對象不能被重載

  • 等級:Major

  • 緣由:重載一個對象改變了它自身的行爲可能會影響到代碼中的其它對象。若是不當心重載內置對象可能會對其它的代碼產生災難性的危害。這條規則檢測以下內置對象是否被重載:

    基本對象 - Object, Function, Boolean, Symbol, Error, EvalError, InternalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError;

    數據和時間- Number, Math, Date;

    文本處理-String, RegExp;

    各類數組- Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Unit16Array, Int32Array, Uint32Array, Float32Array, Float64Array;

    集合-Map, Set, WeakMap, WeakSet;

    結構化數據- ArrayBuffer, DataView, JSON;

    控制抽象的關鍵字-Promise;

    反射-Reflect,Proxy;

    國際化-Intl;

    非標準的對象-Generator, Iterator, ParallelArray, StopIteration.

14. 沒有用的存儲應該被及時的移除

  • 等級:Major

  • 緣由:若是一個變量在賦值後沒有被使用,則會產生無用的存儲。只有儘快釋放它,纔不會對代碼形成危害。即使不產生危害,對資源也是一種浪費。所以,要保證全部定義的變量都要被用到。

  • 建議以下的方式:

    function pow(a, b) { if (b == 0) { return 0; } var x = a; for (var i = 1, i < b, i++) { x = x * a; } return x; } 
  • 不建議以下的方式:

    function pow(a, b) { if (b == 0) { return 0; } var x = a; for (var i = 1, i < b, i++) { x = x * a; //Dead store because the last return statement should return x instead of returning a } return a; } 

15. 保證函數調用時傳入的參數都被使用

  • 等級:Critical

  • 緣由:在JavaScript中你能夠在調用函數時傳入比函數自身要求的更多的參數,可是,要保證額外的參數可以被使用。

  • 建議以下的方式:

    function doSomething(a, b) { compute(arguments); } doSomething(1, 2, 3) // Compliant 
  • 不建議以下的方式:

    function say(a, b) { print(a + ' ' + b); } say('hello', 'world', '!'); // Noncompliant; last argument is not used 

16. 不要在循環內部定義函數

  • 等級:Major

  • 緣由:在循環內部定義函數會形成不可預料的結果,由於這樣定義的函數生命週期很短,同時其中的變量值也會不斷被更新。

  • 不建議以下的方式:

    var funs = []; for (var i = 0; i < 13; i++) { funs[i] = function () { // Non-Compliant return i; }; } print(funs[0] ()); // 13 instead of 0 print(funs[1] ()); // 13 instead of 1 print(funs[2] ()); // 13 instead of 2 print(funs[3] ()); // 13 instead of 3 ... 

17. 函數不能被二次定義

  • 等級:Major

  • 緣由:這條規則檢測在同一個做用域內是否有同名的函數。事實上,頗有可能產生這種現象,可是JavaScript引擎只會執行最後一次聲明的那個函數。這種重複聲明函數的代碼一般會帶來bug而且會讓代碼很亂。

  • 建議以下的方式:

    fun(); // prints "foo" function fun() { print('foo'); } fun(); // prints "foo" 或者是: fun(); // prints "foo" function fun() { print('foo'); } fun(); // prints "foo" function printBar() { print('bar'); } fun(); // prints "foo" 
  • 不建議以下的方式:

    fun(); // prints "bar" // first declaration of the function function fun() { print('foo'); } fun(); // prints "bar" // redeclaration of the "fun" function: this definition overrides the previous one function fun() { print('bar'); } fun(); // prints "bar" 

18. 關於HTML-STYLE的註釋不能使用

  • 等級:Major

  • 緣由:這種註釋的風格不是JavaScript規範的一部分因此不可以使用

  • 建議以下的方式:

    // Compliant
    /* Compliant */ 
  • 不建議以下的方式:

    <!-- Noncompliant --> 

19. 二元運算符兩側不能使用相同的式子

  • 等級:Critical

  • 緣由:
    使用相同值的二元運算符每每會形成錯誤。這種狀況的邏輯操做符,要麼是個粘貼拷貝的錯誤,要麼就是在浪費代碼,須要修改。若是出如今布爾表達式中,結果就是能夠肯定的,沒有意義。

  • 建議以下的方式:

    doZ(); if (a == b) { doX(); } if (a == b) { doW(); } var j = 1; var k = 0; 
  • 不建議以下的方式:

    if (a == a) { // always true doZ(); } if (a != a) { // always false doY(); } if (a == b && a == b) { // if the first one is true, the second one is too doX(); } if (a == b || a == b) { // if the first one is true, the second one is too doW(); } var j = 5 / 5; //always 1 var k = 5 - 5; //always 0 
  • 例外:在測試值是不是NAN狀況下是可使用的,由於只有NAN不等於自身。

    f(f !== f) { // test for NaN value console.log('f is NaN'); } var i = 1 << 1; // Compliant var j = a << a; // Noncompliant 

20. 嵌套的代碼塊不能爲空

  • 等級:Major
  • 緣由:大部分爲空的嵌套代碼塊是忘記了,或者丟失了。這種代碼塊沒有任何意義。
  • 不建議以下的方式:

    for (var i = 0; i < length; i++) { } // Empty on purpose or missing piece of code ? 
  • 例外:若是代碼塊中嵌套着註釋,則這個代碼塊能夠爲空。

21. 屬性名稱在文本對象中重複

  • 等級:Critical
  • 緣由:JavaScript容許屬性名在文本對象中重複。可是,將會以最後一次聲明的屬性爲最終的值。所以,改變相同屬性名的值將會產生意想不到的錯誤。而且在較爲嚴格的檢測中這種重複是不容許的。
  • 建議以下的方式:

    var data = { 'key': 'value', '1': 'value', 'key2': 'value', 'key3': 'value', key4: 'value', \u006bey5: 'value', '\u006bey6': 'value', '\x6bey7': 'value', 1b: 'value' } 
  • 不建議以下的方式:

    var data = { 'key': 'value', '1': 'value', 'key': 'value', // Noncompliant - duplicate of "key" 'key': 'value', // Noncompliant - duplicate of "key" key: 'value', // Noncompliant - duplicate of "key" key: 'value', // Noncompliant - duplicate of "key" 'key': 'value', // Noncompliant - duplicate of "key" 'key': 'value', // Noncompliant - duplicate of "key" 1: 'value' // Noncompliant - duplicate of "1" } 

22. 在」IF/ELSE IF」和」SWITCH/CASES」代碼塊中,不能出現相同的條件

  • 等級:Critical
  • 緣由: 這兩種分支代碼塊會執行第一個符合條件的語句,若是出現兩個相同的條件,頗有多是copy/paste錯誤,或者是程序員考慮不周。不管是哪一個都會產生錯誤。對於switch代碼塊,若是條件中存在break則不會執行接下來的條件,直接跳出該代碼塊。對於if代碼塊雖然沒有break,但會覆蓋前一個條件設定的值,出現錯誤。
  • 建議以下的方式:

    if (param == 1) openWindow(); else if (param == 2) closeWindow(); else if (param == 3) moveWindowToTheBackground(); switch (i) { case 1: //... break; case 3: //... break; default: // ... break; } 
  • 不建議以下的方式:

    if (param == 1) openWindow(); else if (param == 2) closeWindow(); else if (param == 1) // Noncompliant moveWindowToTheBackground(); switch (i) { case 1: //... break; case 3: //... break; case 1: // Noncompliant //... break; default: // ... break; } 

23. ==和!=不要用在FOR循環中控制終止條件

  • 等級:Critical
  • 緣由:使用==和!=控制for循環的終止條件是比較危險的。由於可能形成無限循環。
  • 建議以下的方式:

    for (var i = 1; i <= 10; i += 2) // Compliant { //... } 
  • 不建議以下的方式:

    for (var i = 1; i != 10; i += 2) // Noncompliant. Infinite; i goes from 9 straight to 11. { //... } 
  • 例外:若是測試的是null則可使用==和!=,好比:

    for (inti = 0; arr[i] != null; i++) { // ... } for (inti = 0; (item = arr[i]) != null; i++) { // ... } 

24. 選擇器獲得的結果必定要用LENGTH判斷

  • 等級:Critical
  • 緣由:一旦使用選擇器,你會想知道是否找到了所需的元素。由於選擇器老是返回一個對象(或者DOM元素集合),最好的方式是判斷返回對象的length屬性。
  • 建議以下的方式:

    // Testing whether a selection contains elements.
    if ($('div.foo').length > 0) { // this code only runs if elements were found // ... } 
  • 不建議以下的方式:

    if ($('div.foo')) { // Noncompliant // this code always runs, even when the selector didn't match any elements // ... } 

25. SETTERS不能返回值

  • 等級:Critical
  • 緣由:用set關鍵字定義的函數會自動的返回傳出的值。所以,任何自定義的返回值都會被忽略,確切的說這是一種錯誤。
  • 建議以下的方式:

    var person = { // ... set name(name) { this.name = name; } } 
  • 不建議以下的方式:

    var person = { // ... set name(name) { this.name = name; return 42; // Noncompliant } } 

26. 用邏輯短路防止出現空的錯誤

  • 等級:Blocker
  • 緣由:在測試元素是否爲空時,須要注意使用邏輯短路防止對空元素進行操做,產生錯誤。
  • 建議以下的方式:

    if (str != null && str.length == 0) { console.log('String is empty'); } if (str != undefined && str.length == 0) { console.log('String is empty'); } if (str == null || str.length > 0) { console.log('String is not empty'); } if (str == undefined || str.length > 0) { console.log('String is not empty'); } 
  • 不建議以下的方式:

    if (str == null && str.length == 0) { console.log('String is empty'); } if (str == undefined && str.length == 0) { console.log('String is empty'); } if (str != null || str.length > 0) { console.log('String is not empty'); } if (str != undefined || str.length > 0) { console.log('String is not empty'); } 

27. 調用PARSEINT函數要帶兩個參數

  • 等級:Critical
  • 緣由:parseInt函數有兩個版本的,一個是隻有一個參數的,而另外一個是須要兩個參數的。然而,舊版的瀏覽器不支持一個參數的parseInt方法。
  • 好的方法:

    parseInt("010", 10); 
  • 不建議以下的方式:

    parseInt("010"); // Noncompliant; pre-2013 browsers may return 8 

28. 在分支語句中,兩個不一樣的分支不要執行相同的操做

  • 等級:Major
  • 緣由:在switch語句中兩不一樣的case執行相同的代碼和在if語句中兩個不一樣的條件執行相同的操做都是代碼重複的表現,有時甚至會報錯。所以,須要將兩個條件進行合併。
  • 建議以下的方式:

    switch (i) { case 1: case 3: doSomething(); break; case 2: doSomethingDifferent(); break; default: doTheRest(); } if ((a >= 0 && a < 10) || (a >= 20 && a < 50)) { doTheThing(); else if (a >= 10 && a < 20) { doTheOtherThing(); } else { doTheRest(); } 或者是: switch (i) { case 1: doSomething(); break; case 2: doSomethingDifferent(); break; case 3: doThirdThing(); break; default: doTheRest(); } if (a >= 0 && a < 10) { doTheThing(); else if (a >= 10 && a < 20) { doTheOtherThing(); } else if (a >= 20 && a < 50) { doTheThirdThing(); } else { doTheRest(); } 
  • 不建議以下的方式:

    switch (i) { case 1: doSomething(); break; case 2: doSomethingDifferent(); break; case 3: // Noncompliant; duplicates case 1's implementation doSomething(); break; default: doTheRest(); } if (a >= 0 && a < 10) { doTheThing(); else if (a >= 10 && a < 20) { doTheOtherThing(); } else if (a >= 20 && a < 50) { doTheThing(); // Noncompliant; duplicates first condition } else { doTheRest(); } CompliantSolution: switch (i) { case 1: case 3: doSomething(); break; case 2: doSomethingDifferent(); break; default: doTheRest(); } if ((a >= 0 && a < 10) || (a >= 20 && a < 50)) { doTheThing(); else if (a >= 10 && a < 20) { doTheOtherThing(); } else { doTheRest(); } 

29. 變量不要作沒有用的增加

  • 等級:Critical
  • 緣由:將變量增加或者遞減而不進行存儲是典型的代碼冗餘的表現,更有甚者會產生錯誤。
  • 建議以下的方式:

    var i = 0; i++; 
  • 不建議以下的方式:

    var i = 0; i = i++; // Noncompliant; i is still zero 

30. 不要重複使用變量或者方法名

  • 等級:Major
  • 緣由:這條規則檢驗聲明變量或方法時不要使用已經存在的名子。事實上,重複使用相同的名子在語法上是容許的,可是結果讓人沒法預測。所以可能會產生沒法預測的錯誤。
  • 建議以下的方式:

    var a = 'foo'; function otherName() { } console.log(a); function myFunc(arg) { var newName = 'event'; } fun(); // prints "foo" function fun() { print('foo'); } fun(); // prints "foo" function printBar() { print('bar'); } printBar(); // prints "bar" 
  • 不建議以下的方式:

    var a = 'foo'; function a() { } // Noncompliant console.log(a); // prints "foo" function myFunc(arg) { var arg = 'event'; // Noncompliant, argument value is lost } fun(); // prints "bar" function fun() { console.log('foo'); } fun(); // prints "bar" function fun() { // Noncompliant console.log('bar'); } fun(); // prints "bar" 

31. 變量不要重複聲明

  • 等級:Major
  • 緣由:這條規則檢驗變量是否被重複定義。這種重複定義的變量每每會形成沒法預測的錯誤。
  • 建議以下的方式:

    var a = 'foo'; var b = 'bar'; function f(e) { var g = 'event'; } 
  • 不建議以下的方式:

    var a = 'foo'; var a = 'bar'; // Non-Compliant function f(e) { var e = 'event'; // Non-Compliant } 

32. 變量不能本身賦值給本身

  • 等級:Major
  • 緣由:變量賦值給本身是沒有意義的。要麼是個代碼冗餘,要麼是個錯誤。
  • 建議以下的方式:

    function setName(name) { this.name = name; } 
  • 不建議以下的方式:

    function setName(name) { name = name; } 

Misra----4條

1. 不能使用"CONTINUE"

  • 等級:Critical
  • 緣由:continue是個非結構控制塊。它會下降代碼測試性,可讀性和可維護性。應該使用結構化控制塊(例如if)來代替。
  • 建議以下的方式:

    for (i = 0; i < 10; i++) { if (i != 5) { /* Compliant */ alert('i = ' + i); } } 
  • 不建議以下的方式:

    for (i = 0; i < 10; i++) { if (i == 5) { continue; /* Non-Compliant */ } alert('i = ' + i); } 

2. 」SWITCH」代碼塊至少有3個」CASE」

  • 等級:Minor
  • 緣由:若是低於三個的話使用if會更方便些。
  • 建議以下的方式:

    if (variable == 0) { doSomething(); } else { doSomethingElse(); } 
  • 不建議以下的方式:

    switch (variable) { case 0: doSomething(); break; default: doSomethingElse(); break; } 

3. 逗號操做符不要在表達式中使用

  • 等級:Major
  • 緣由:逗號操做符鏈接兩個表達式,從左到右執行它們。這種方式不利於代碼的可讀性和可維護性,而且這種方式也能夠用其它方式替代。
  • 建議以下的方式:

    a += 2; i = a + b; 
  • 不建議以下的方式:

    i = a += 2, a + b; // What's the value of i ? 
  • 例外:在for循環中的控制部分是可使用逗號分割表達式的。

    for(i = 0, j = 5; i < 6; i++, j++) { ... } 

4. 代碼段不該該被註釋掉

  • 等級:Minor
  • 緣由: 開發人員不能註釋代碼,由於會影響代碼可讀性。再也不使用的代碼就刪除。

5. 函數中沒有使用過的變量應該被刪除

  • 等級:Major
  • 緣由:函數中沒有被使用過的參數不會影響函數的操做結果,應該被刪掉。
  • 建議以下的方式:

    function doSomething(b) { return compute(b); } 
  • 不建議以下的方式:

    function doSomething(a, b) { // "a" is unused return compute(b); } 
  • 例外:當函數存在返回值時,有些變量可能須要做爲某些函數的標誌。例如:

    $(['first','last']).each(function (i, value) { computeSomethingWithValue(value); }); var myFirsCallBackFunction = function (p1, p2, p3, p4) { //unused p2 is not reported but p4 is return p1 + p3; } var mySecondCallBackFunction = function (p1, p2, p3, p4) { //unused p1, p2 and p3 are not reported return p4; } var myThirdCallBackFunction = function (p1, p2, p3, p4) { //unused p1 is not reported but p3 and p4 are return p2; } 

Pitfall----19條

1. 保留字不能用做標識符

  • 等級:Critical
  • 緣由:如下的單詞是JavaScript保留字,用於JavaScript之後的拓展,不能做爲標識符使用。

    await
    class const enum exports extends implements import interface let package private protected public static super yield 
  • 建議以下的方式:

    var elements = document.getElementsByName('foo'); // Compliant 
  • 不建議以下的方式:

    var package = document.getElementsByName('foo'); // Noncompliant var someData = { package: true }; // Compliant, as it is not used as an identifier here 

2. 「SWITCH」塊中不能包括沒有CASE關鍵詞的分支

  • 等級:Critical
  • 緣由:即使是合法的,這樣作也會大大下降代碼可讀性,嚴重時,會形成意想不到的錯誤。

  • 建議以下的方式:

    Case1
    switch (day) { case MONDAY: case TUESDAY: case WEDNESDAY: doSomething(); break; ... } Case2 switch (day) { case MONDAY: break; case TUESDAY: compute(args); // put the content of the labelled "for" statement in a dedicated method break; /* ... */ } 
  • 不建議以下的方式:

    Case1, The code is syntactically correct but the behavior is not the expecte done switch (day) { case MONDAY: case TUESDAY: WEDNESDAY: // instead of "case WEDNESDAY" doSomething(); break; ... } Case2,the code is correct and behaves as expected but is hardly readable switch (day) { case MONDAY: break; case TUESDAY: foo: for (i = 0; i < X; i++) { /* ... */ break foo; // this break statement doesn't relate to the nesting case TUESDAY /* ... */ } break; /* ... */ } 

3. 不能將」UNDEFINED」賦值給變量

  • 等級:Critical
  • 緣由:undefined是一個屬性還沒有建立的標誌。若是將它賦值給已經存在的屬性,你將沒法區分變量是否建立。更好的方式是你可使用null代替。

  • 建議以下的方式:

    var myObject = { }; // ... myObject.fname = null; // ... if (myObject.lname == undefined) { // property not yet created } if (myObject.fname == undefined) { // no real way of knowing the true state of myObject.fname } 
  • 不建議以下的方式:

    var myObject = { }; // ... myObject.fname = undefined; // Noncompliant // ... if (myObject.lname == undefined) { // property not yet created } if (myObject.fname == undefined) { // no real way of knowing the true state of myObject.fname } 

4. 不要使用安位操做符

  • 等級:Major
  • 緣由:JavaScript沒有integer類型,可是它有安位操做符<<, >>, >>>, ~, &,I。這種操做會首先將float類型轉換爲integer類型,而後再轉換回來,並不能像C那樣高效。更況且,支持這種操做的瀏覽器也不多。

  • 建議以下的方式:

    if (a && b) { ... } var oppositeSigns = false; if ((x < 0 && y > 0) || (x > 0 && y < 0)) { oppositeSigns = true; } 
  • 不建議以下的方式:

    if (a & b) { ... } // Noncompliant; & used in error var oppositeSigns = ((x ^ y) < 0); // Noncompliant; there's a clearer way to test for this 

5. 構造方法不能單獨使用

  • 等級:Major
  • 緣由:有些工程師喜歡單獨調用構造方法而不將值賦值給變量。這是有百害無一利的作法,由於這樣構造的對象就沒法在其它地方使用了。

  • 建議以下的方式:

    var something = new MyConstructor(); // Compliant 
  • 不建議以下的方式:

    new MyConstructor(); // Non-Compliant 

6. 要使用大括號做爲範圍控制

  • 等級:Major
  • 緣由:雖然沒有語法的錯誤,可是不使用大括號會下降代碼的可讀性。還有可能形成邏輯上的錯誤。

  • 建議以下的方式:

    if (condition) { executeSomething(); checkSomething(); } 
  • 不建議以下的方式:

    // the two statements seems to be attached to the if statement, but that is only true for the first one:
    if (condition) executeSomething(); checkSomething(); 

7. 函數的參數名不能相同。

  • 等級:Critical
  • 緣由:函數的參數名應該不同以防操做產生混亂。實際上,若是存在相同的參數名,最後一個參數將會覆蓋前邊相同的參數。這種作法是沒有意義的,下降了可讀性和可維護性。

  • 建議以下的方式:

    function compute(a, b, c) { // Compliant } 
  • 不建議以下的方式:

    function compute(a, a, c) { // Noncompliant } 

8. 函數調用的參數不要在新的一行裏開始

  • 等級:Critical
  • 緣由:由於「;」一行的結束符在JavaScript中不是必須的,若是函數調用的參數在新的一行開始就會讓代碼可讀性大大下降。可能會致使錯誤和之後維護的問題。

  • 建議以下的方式:

    // define a function
    Either
    var fn = function () { //... }; // <-- semicolon added // then execute some code inside a closure (function () { //... }) (); Or var fn = function () { //... }(function () { // <-- start function call arguments on same line //... }) (); 
  • 不建議以下的方式:

    var fn = function () { //... }(function () { // Noncompliant //... }) (); 

9. 不要使用UNDERFINED做爲變量

  • 等級:Critical
  • 緣由:開發人員有可能使用undefined做爲變量,可是這個關鍵字是區別變量是否建立的標誌。若是被覆蓋,你將沒法區別變量是否存在。

  • 建議以下的方式:

    function foo() { var bob = 1; // anything is better than naming it 'undefined' if (nonExistantVar == undefined) { // ... } } 
  • 不建議以下的方式:

    function foo() { var undefined = 1; // Noncompliant if (nonExistantVar == undefined) { // this logic doesn't work now // ... } } 

10. 八進制不能被使用

  • 等級:Major
  • 緣由:儘管JavaScript是徹底支持八進制的,可是大部分開發人員不能熟練的使用八進制。他們可能會將八進制當作十進制數字來處理。

  • 建議以下的方式:

    var myNumber = 8; 
  • 不建議以下的方式:

    var myNumber = 010; // myNumber will hold 8, not 10 - was this really expected? 

11. 只能在」WHILE」,」DO」和」FOR」中使用LABEL

  • 等級:Major
  • 緣由:在任何代碼塊中均可以識別label,可是隻能在」while」,」do」和」for」使用label。在其餘結構中使用label都會使結構混亂,代碼難以理解。

  • 建議以下的方式:

    myLabel: for (i = 0; i < 10; i++) { // Compliant print('Loop'); break myLabel; } 
  • 不建議以下的方式:

    myLabel: if (i % 2 == 0) { // Noncompliant if (i == 12) { print('12'); break myLabel; } print('Odd number, but not 12'); } 

12. 源文件中不能有重複的模塊

  • 等級:Major
  • 緣由:若是存在重複的模塊就會產生錯誤。

13. SWITCH的每一個條件結尾都要有BREAK

  • 等級:Critical
  • 緣由:若是條件中沒有break,那麼程序就會繼續往下執行。雖然有時候這是開發人員有意設置的,可是更大可能的是代碼錯誤。

  • 建議以下的方式:

    switch (myVariable) { case 1: foo(); break; case 2: doSomething(); break; default: doSomethingElse(); break; } 
  • 不建議以下的方式:

    switch (myVariable) { case 1: foo(); break; case 2: // Both 'doSomething()' and 'doSomethingElse()' will be executed. Is it on purpose ? doSomething(); default: doSomethingElse(); break; } 
  • 例外:如下狀況,該規則認爲是合理的:

    switch (myVariable) { case 0: // Empty case used to specify the same behavior for a group of cases. case 1: doSomething(); break; case 2: // Use of return statement return; case 3: // Use of throw statement throw new IllegalStateException(); case 4: // Use of continue statement continue; default: // For the last case, use of break statement is optional doSomethingElse(); } 

14. 不能在對象外使用THIS

  • 等級:Minor
  • 緣由:若是在對象外使用this,它將指代全局的對象window。顯而易見,這樣將會形成難以控制的錯誤。

  • 建議以下的方式:

    foo = 1; console.log(foo); function MyObj() { this.foo = 1; } MyObj.func1 = function () { if (this.foo == 1) { // ... } } 
  • 不建議以下的方式:

    this.foo = 1; // Noncompliant console.log(this.foo); // Noncompliant function MyObj() { this.foo = 1; // Compliant } MyObj.func1 = function () { if (this.foo == 1) { // Compliant // ... } } 

15. 相同的名字不能在相同的做用域內重複聲明

  • 等級:Major
  • 緣由:不能在一個做用域內使用相同的名子聲明變量或函數。這不但會下降代碼可讀性,並且會致使沒必要要的錯誤。

  • 建議以下的方式:

    var fun = function fun() { } * 不建議以下的方式: var fun; function fun() { } 

16. 變量聲明時必定要帶VAR

  • 等級:Major
  • 緣由:JavaScript變量的做用域很難掌握準確。若是存在全局變量會讓這種狀況變得更糟。

  • 建議以下的方式:

    function f() { var i = 1; for (var j = 0; j < array.length; j++) { // ... } } 
  • 不建議以下的方式:

    function f() { i = 1; // Noncompliant; i is global for (j = 0; j < array.length; j++) { // Noncompliant; j is global now too // ... } } 

17. 變量須要在使用前聲明

  • 等級:Major
  • 緣由:JavaScript困擾開發人員的最大問題就是做用域。主要的緣由是雖然JavaScript看起來像是相似C語言的。可是實際並非。C語言家族有明顯的的做用域標誌,它們是經過塊來控制的,好比if塊,你能夠在裏邊創建新的變量,這樣並不會影響塊之外的做用域,而JavaScript卻不能夠。爲了儘可能避免做用域的困擾,在變量使用前必定要先聲明。

  • 建議以下的方式:

    var x = 1; function fun() { print(x); if (something) { x = 42; } } fun(); // Print "1" 
  • 不建議以下的方式:

    var x = 1; function fun() { alert(x); // Noncompliant as x is declared later in the same scope if (something) { var x = 42; // Declaration in function scope (not block scope!) shadowsglobal variable } } fun(); // Unexpectedly alerts "undefined" instead of "1" 

18. 變量不能被覆蓋

  • 等級:Major
  • 緣由:覆蓋一個在外域的變量會下降代碼可讀性和可維護性。更有甚者,會引入錯誤。

  • 建議以下的方式:

    show: function (point, element) { if (!this.drops.length) return; var drop, affected = [ ]; this.drops.each(function (aDrop) { if (Droppables.isAffected(point, element, aDrop)) affected.push(aDrop); }); 
  • 不建議以下的方式:

    show: function (point, element) { if (!this.drops.length) return; var drop, affected = [ ]; this.drops.each(function (drop) { // Non-Compliant; defines a new 'drop' parameter if (Droppables.isAffected(point, element, drop)) affected.push(drop); }); 

19. 基本類型定義時不能使用包裝對象的方式

  • 等級:Major
  • 緣由:使用基本類型包裝的對象定義變量是沒有意義的。

  • 建議以下的方式:

    var x = false; if (x) { alert('hi'); } 
  • 不建議以下的方式:

    var x = new Boolean(false); if (x) { alert('hi'); // Shows 'hi'. } 

安全相關——7條

1. .ALERT()函數不該該被使用

  • 等級:Info
  • 緣由:在開發的過程當中,會使用alert()進行debug,可是發佈的應用中,這種彈出方式可能會給攻擊者泄露敏感信息。

  • 不建議以下使用方式:

    if (unexpectedCondition) { alert('Unexpected Condition'); } 

2. 代碼不該該動態注入執行,以防止出現EVAL注入問題

  • 等級:Critical
  • 緣由:eval是在運行的時候執行任意代碼的函數,通常來講,用eval函數是很危險的,由於它能夠執行任意的代碼,若是通過必須使用該函數,則要特別注意該函數處理的任何用戶輸入數據。

  • 不建議以下使用方式:

    eval(code_to_be_dynamically_executed) 

3. CONSOLE LOGGING不該該被使用

  • 等級:Info
  • 緣由:Debug信息在開發過程當中頗有用,可是在發佈的版本中,特別是客戶端保留Debug信息,會形成敏感信息泄露,使瀏覽器運行緩慢,甚至是瀏覽器進程崩潰錯誤。

  • 不建議以下使用方式:

    console.log(password_entered); 

4. 跨文檔消息應該被限制

  • 等級:Critical
  • 緣由:HTML5引入了一個在跨域頁面之間通信的方法,爲了下降向目標域以及未知域中傳遞敏感消息的危險,每次調用Window.postmessage方法的時候都須多加註意,不該該使用通配符*。

  • 不建議以下的使用方式:

    var myWindow = document.getElementById('myIFrame').contentWindow; myWindow.postMessage(message, '*'); // Noncompliant; how do you know what you loaded in 'myIFrame' is still there? 

5. DEBUGGER語句不該該被使用

  • 等級:Critical
  • 緣由:Debugger語句能夠在程序的任何地方聲明來暫停程序執行。利用debugger語句就像在代碼中加了一個斷點同樣。在發佈的代碼中,任何debugger語句都必須被移除。

  • 不建議以下的使用方式:

    for (i = 1; i < 5; i++) { // Print i to the Output window. Debug.write('loop index is ' + i); // Wait for user to resume. debugger; } 
  • 建議以下的使用方式:

    for (i = 1; i < 5; i++) { // Print i to the Output window. Debug.write('loop index is ' + i); } 

6. 無用的「IF(TRUE) {...}」 以及「IF(FALSE){...}」 代碼塊應該被移除

  • 等級:Major
  • 緣由:被false包括的代碼塊可能沒有實際用處,被true聲明的代碼塊是冗餘的,而且下降了代碼的可讀性。
  • 不建議以下的使用方式:

    if (true) { // Noncompliant doSomething(); }...if (false) { // Noncompliant doSomethingElse(); } if (!options || options === true) { doThirdThing(); } // Noncompliant; always true 
  • 建議的使用方式:

    doSomething(); doThirdThing(); 

7. 不要使用本地數據庫,本地數據庫,也就是WEB SQL DATABASE,是隨着HTML5規範加入的在瀏覽器端運行的輕量級數據庫。

  • 等級:Critical
  • 緣由:本地數據庫標準在W3C標準中已經不推薦使用,此外,使用本地數據庫也會產生相應的安全問題。

  • 不建議以下的使用方式:

    var db = window.openDatabase('myDb', '1.0', 'Personal secrets stored here', 2 * 1024 * 1024); //Noncompliant 

性能相關----5條

1. 在靠類型選擇元素的時候應該利用「[TYPE=...]」

  • 等級:Major
  • 緣由:在JQuery中,和type="<element_type>"均可以用來選擇元素,可是type="<element_type>"由於利用了本地的DOM querySelectorAll()方法,因此更快一些。

  • 不建議以下的方式:

    var input = $( 'form input:radio' ); // Noncompliant 
  • 建議以下的方式:

    var input = $( 'form input[type=radio]' ); // Compliant 

2. 在JQUERY中,查找某個元素的子節點時,若是已知該元素的ID,則應該用FIND方法,這樣可讓查詢變得更快,使應用相應更加及時。

  • 等級:Major
  • 不建議以下的方式:

    var $productIds = $('#products div.id'); // Noncompliant - a nested query for Sizzle selector engine 
  • 建議以下的方式:

    var $productIds = $('#products').find('div.id'); // Compliant - #products is already selected by document.getElementById() so only div.id needs to go through Sizzle selector engine 

3. 不同意的JQUERY方法不該該被使用

  • 等級:Major
  • 緣由:不同意的方法是將會被取代的方法,而且最終會被移除,下面的方法是不建議被使用的方法 .andSelf() .context .die() .error() jQuery.boxModel jQuery.browser jQuery.sub() jQuery.support .live() .load() .selector .size() .toggle() .unload()

4. 選擇結果應該被保存

  • 等級:Major
  • jQuery不會替你緩存元素,若是你選擇了你可能還會用到的變量,你應該將選擇結果保存在變量中。

  • 不推薦以下的方式:

    $( 'p' ).hide(); $( 'p' ).show(); 
  • 推薦以下的方式:

    var paragraph = $( 'p' ); paragraph.hide(); paragraph.show(); 
  • 例外狀況:DOM變化時,保存的selections沒有更新, 以下:

    var paragraph = $('p'); // ... paragraph = $('p'); 
  • 觸發本條規則的重複值爲2

5. 通配選擇器不該該被使用

  • 等級:Major
  • 緣由:使用通配選擇器會使影響性能,使應用變慢,因此應該限制通配選擇器的使用。
  • 不建議以下的方式:

    $( '.buttons > *' ); // Noncompliant; extremely expensive 
  • 建議以下的方式:

    $( '.buttons' ).children(); // Compliant 

約定規範——10條

1. 註釋不該該寫在每一行的最後面

  • 等級:Info
  • 緣由:關於單行的註釋,不建議將註釋寫在該行代碼的最後,爲了增長程序的可讀性,建議將註釋寫在代碼的前一個空行上。

  • 不建議以下的方式:

    var a1 = b + c; // This is a trailing comment that can be very very long 
  • 建議以下的方式:

    // This very long comment is better placed before the line of code
    var a2 = b + c; 當註釋只有一個單詞的時候,容許註釋寫在代碼的後面,這是一種特例 doSomething(); //FIXME 

2. 每一條聲明需要由「;」結尾

  • 等級:Major
  • 緣由:雖然在JavaScript中,在聲明後面添加「;」不是強制性的,可是省略「;」是一種不值得提倡的作法,在有些狀況下可能會引發意想不到的結果。

  • 不建議以下的方式:

    function fun() { return // Noncompliant. ';' implicitly inserted at end of line 5 // Noncompliant. ';' implicitly inserted at end of line } print(fun()); // prints "undefined", not "5" 
  • 建議以下的方式:

    function fun() { return 5; } print(fun()); 

3. 文件後面應該包含一個空行

  • 等級:Minor
  • 緣由:這條規則會使得在利用一些工具,例如Git的時候配合的更好。

  • 建議以下的使用方式:

    class Test { } \\newline at end of file 

4. FUNCTION的名稱應該聽從命名規範

  • 等級:Major
  • 緣由: 共同遵照一個命名規範是團隊合做高效的一個關鍵點。某些函數命名方式不建議被使用。
  • 不建議以下的方式:

    function DoSomething(){...} 
  • 建議以下的方式:

    function doSomething(){...} 
  • 默認的規範正則表達式爲:^[a-z][a-zA-Z0-9]*$

5. JQUERY的緩存變量命名應該聽從規範

  • 等級:Major
  • 緣由:和第4點相同,JQuery的變量命名也須要符合必定的規範。

  • 默認的命名檢查正則表達式爲:^\$[a-z][a-zA-Z0-9]*$

6. 一行代碼不要太長

  • 等級:Info
  • 緣由:若是一行代碼太長,閱讀起來不利於理解代碼的含義,這裏一行默認的最大代碼長度爲80。

7. 一行代碼結束後不該該額外的空格

  • 等級:Minor
  • 緣由:結尾的空格是無用的,且不該該保留在代碼中,在比較不一樣版本的相同文件時,末尾的空格可能會形成影響。

  • 不建議以下的方式:

    // The following string will error if there is a whitespace after '\'
    var str = "Hello \ World"; 

8. 聲明STRING類型的變量是須要用單引號

  • 等級:Minor
  • 緣由:將字符串用單引號聲明而非雙引號。

  • 不建議以下的方式:

    var firstParameter = "something"; 
  • 建議以下的方式:

    var firstParameter = 'something'; 

9. 源代碼文件應該有足夠的註釋

  • 等級:Minor
  • 緣由:代碼註釋量必須達到必定的閾值。默認的代碼註釋量爲15%

10. STATEMENTS應該被分紅多行

  • 等級:Minor
  • 緣由:爲了便於閱讀,不要將許多statement放在一行

  • 不建議以下的方式:

    if(someCondition) doSomething(); 
  • 建議以下的方式:

    if(someCondition) { doSomething(); } 
  • 例外狀況:遇到只包含一個statement的匿名函數時例外,以下:

    onEvent(function() { doSomething(); }); // Compliant onEvent(function(p) { doSomething(); return p %2 ;}); // Noncompliant 

瀏覽器兼容性問題----2條

1. 命名函數表達式不該該被使用

  • 等級:Major
  • 緣由:某些瀏覽器不支持命名函數表達式,好比IE8

  • 不建議以下的方式:

    f = function fun(){}; // Non-Compliant; named function expression 
  • 建議以下的方式:

    fun = function(){}; // Compliant; function expression 
  • 例外狀況:ECMAScript6的generator function不被包含在內,以下:

    function* f() {} // Compliant; generator function. 

2. 在塊中不該該直接使用函數表達式

  • 等級:Major
  • 緣由:雖然大多數script引擎支持在塊中聲明函數,可是它不是ECMAScript5以及其以前版本的標準,且各個瀏覽器的處理方式是不一致的。若是你的目標瀏覽器不支持ECMAScript6,那麼在塊中利用變量定義一個函數表達式。

  • 不建議以下的使用方式:

    if (x) {  function foo() {} } 
  • 建議以下的方式:

    if (x) { var foo = function() {} } 

一些建議——8條

1. 控制語句,IF,FOR,WHILE,SWITCH,以及TRY不該該嵌套的太深

  • 等級:Minor
  • 緣由:嵌套太深的代碼難以閱讀,重構以及維護

  • 不建議以下的方式:

    if (condition1) { // Compliant - depth = 1 /* ... */ if (condition2) { // Compliant - depth = 2 /* ... */ for (inti = 0; i < 10; i++) { // Compliant - depth = 3, not exceeding the limit /* ... */ if (condition4) { // Non-Compliant - depth = 4 if (condition5) { // Depth = 5, exceeding the limit, but issues are only reported on depth = 4 /* ... */ } return; } } } } 
  • 默認觸發問題報告的嵌套深度爲3.

2. 表達式不該該太複雜

  • 等級:Major
  • 緣由:表達式的複雜程度是由&&,||,以及?,ifTrue:ifFalse操做符定義的,一個表達式不該該有超過三個的操做符,以增長表達式的可讀性。

  • 默認觸發值爲3.

3. FUNCTIONS不該該有太多行

  • 等級:Major
  • 緣由:一個較大的函數集合了許多功能,這樣的函數不可避免的難以理解以及維護。若是超過了閾值,則強烈建議將函數分紅定義良好的函數。這些較小的函數不只便於理解,並且有利於測試。
  • 例外狀況:
    這個函數忽略了Immediately Invoked Function Expressions (IIFE),函數被建立或者調用時沒有分配名字。以下:

    (function () { // Ignored by this rule  function open() { // Classic function declaration; not ignored // ... }  function read() { // ... }  function readlines() { // ... } }) (); 
  • 觸發此條件的函數的最大行爲300

4. 函數不該該有太多的參數

  • 等級:Major
  • 緣由: 很長的參數列表意味着一個新的結構須要被建立來包含大量的參數,或者說明這個函數作的事情太多了。
  • 不建議以下的方式:

    function doSomething(param1, param2, param3, param4, param5) { ... } 
  • 建議以下的方式:

    public void doSomething(intparam1, intparam2, intparam3, Stringparam4) { ... } 
  • 觸發該問題的參數臨界值爲7,建議用數組或對象代替多個參數。

5. 循環不該該包括多餘一個的BREAK或者CONTINUE語句

  • 等級:Info
  • 緣由:限制循環中的break以及continue語句的數量是一個好的編程習慣。一個break或者continue語句在循環中是能夠接受的,若是多於一個的話,則要考慮重構代碼段。
  • 不建議以下的方式:

    for (var i = 1; i <= 10; i++) { // Noncompliant - 2 continue - one might be tempted to add some logic in between if (i % 2 == 0) { continue; } if (i % 3 == 0) { continue; } alert('i = ' + i); } 

6. 表達式周圍無用的括號應該被移除,以免任何誤解

  • 等級:Major
  • 簡單說明以下:

    return 3; // Compliant return (x); // Non-Compliant return (x + 1); // Non-Compliant intx = (y / 2 + 1); // Non-Compliant inty = (4 + X) * y; // Compliant 

7. 沒有用的本地變量應該被移除

  • 等級:Major
  • 緣由:若是一個本地的變量被聲明而沒有被使用,它應該被移除,這樣會提升代碼維護的效率。

  • 不建議以下的方式:

    function numberOfMinutes(hours) { var seconds = 0; // seconds is never used return hours * 60; } 
  • 建議以下的方式:

    function numberOfMinutes(hours) { return hours * 60; } 

8. ARGUMENTS.CALLER和ARGUMENTS.CALLEE不該該被使用

  • 等級:Major
  • 緣由:這兩個函數在最新的Javascript版本中不建議被使用,可能會對優化形成影響。在ECMAScript5中,這兩個函數在strict模式下都被禁止使用。

  • 不建議以下的方式:

    function whoCalled() { if (arguments.caller == null) //Noncompliant console.log('I was called from the global scope.'); else console.log(arguments.caller + ' called me!'); // Noncompliant console.log(whoCalled.caller); // Noncompliant console.log(whoCalled.arguments); // Noncompliant } 

Bad-practice——6條

1. 多行的STRING變量不該該使用\

  • 等級:Major
  • 緣由:雖然不一樣的script引擎能夠識別多行的string變量(用\方式),可是這種形式沒有被規定在ECMAScript標準中。

  • 不建議以下的方式:

    var myString = 'A rather long string of English text, an error message \  actually that just keeps going and going -- an error \  message to make the Energizer bunny blush (right through \  those Schwarzenegger shades)! Where was I? Oh yes, \  you have got an error and all the extraneous whitespace is \  just gravy. Have a nice day.'; // Noncompliant 
  • 建議以下的方式:

    var myString = 'A rather long string of English text, an error message ' + 'actually that just keeps going and going -- an error ' + 'message to make the Energizer bunny blush (right through ' + 'those Schwarzenegger shades)! Where was I? Oh yes, ' + 'you have got an error and all the extraneous whitespace is ' + 'just gravy. Have a nice day.'; 

2. 下面這種狀況,應該用WHILE代替FOR循環

  • 等級:Major
  • 緣由:當for循環中之定義了狀態時應該用while循環代替

  • 不建議以下的方式:

    for (; condition; ) { /*...*/ } 
  • 建議以下的方式:

    while (condition) { /*...*/ } 

3. 可摺疊的IF語句應該被合併

  • 等級:Major
  • 緣由:合併可摺疊的if語句,從而增長代碼的可讀性

  • 不建議以下的方式:

    if (x != undefined) { if (x === 2) { // ... } } 
  • 建議以下的方式:

    if (x != undefined && x === 2) { // ... } 

4. 在表達式中,BOOLEAN(TRUE和FALSE)值不該該出現

  • 等級:Minor
  • 緣由:移除情況表達式中的true以及false。狀態表達式中出現false以及true是沒有必要的。
  • 不建議以下的方式:

    if (booleanVariable == true) { /* ... */ } if (booleanVariable != true) { /* ... */ } if (booleanVariable || false) { /* ... */ } doSomething(!false); 
  • 建議以下的方式:

    if (booleanVariable) { /* ... */ } if (!booleanVariable) { /* ... */ } if (booleanVariable) { /* ... */ } doSomething(true); 
  • 例外狀況:若是文字的布爾值出如今恆等運算符中則被忽略,以下:

    (=== and !==) 

5. 返回BOOLEAN類型的表達式不該該被放在IF-THEN-ELSE語句中

  • 不建議以下的方式:

    if (expression) { return true; } else { return false; } 
  • 建議以下的方式:

    return expression; return !!expression; 

6. 結尾的逗號不該該被使用

  • 等級:Blocker
  • 緣由:在某些瀏覽器中會出現錯誤,如IE
  • 不建議被使用的方式:

    var settings = { 'foo': oof, 'bar': rab, // Noncompliant - trailing comma }; 
  • 建議的方式:

    var settings = { 'foo': oof, 'bar': rab }; 

其它----2條

1. 」TODO」標籤不能出現

  • 等級:info
  • 緣由:該標籤是一個標記開發人員未來將要在此處實現某些代碼的標誌。有時開發人員會忘記這事,須要對開發人員做出提醒。

  • 不建議以下的方式:

    function doSomething() { // TODO } 

2. 」FIXME」標籤不能出現

  • 等級:Major
  • 緣由:FIXME是開發人員對出現錯誤的代碼進行的標記,有時開發人員可能會忘記,須要進行一下提醒。

    function divide(numerator, denominator) { return numerator / denominator; // FIXME denominator value might be 0 }
相關文章
相關標籤/搜索