交了這麼多年JavaScript學費,你掌握了多少(第二期)

不應嘗試更新“ const”變量

聲明爲的變量const無法修改。不幸的是,這樣做的嘗試並不總是會引發錯誤。在非ES2015環境中,此類嘗試可能會被忽略。

不兼容的代碼示例:

const pi = "yes, please";
pi = 3.14;  // Noncompliant

布爾檢查不應該反轉

反轉布爾比較的結果不必要地複雜。相反,應該進行相反的比較。

不兼容的代碼示例:

if (!(a === 2)) { ... }  // Noncompliant

兼容解決方案:

if (a !== 2) { ... }

大括號和括號應與箭頭功能一致使用

共享的編碼約定使團隊可以有效地協作。當帶箭頭功能的括號使用不符合所配置的要求時,此規則會引起問題。

不兼容的代碼示例:

var foo = (a) => { /* ... */ };  // Noncompliant; remove parens from arg
var bar = (a, b) => { return 0; };  // Noncompliant; remove curly braces from body

兼容解決方案:

var foo = a => { /* ... */ };
var bar = (a, b) => 0;

數組方法的回調應具有return語句

JavaScript中的數組有幾種用於過濾,映射或摺疊的方法,這些方法需要回調。在這樣的回調函數中沒有return語句很可能是一個錯誤。

此規則適用於數組的以下方法:

  • Array.from
  • Array.prototype.every
  • Array.prototype.filter
  • Array.prototype.find
  • Array.prototype.findIndex
  • Array.prototype.map
  • Array.prototype.reduce
  • Array.prototype.reduceRight
  • Array.prototype.some
  • Array.prototype.sort

不兼容的代碼示例:

var merged = arr.reduce(function(a,b){
  a.concat(b);
}; //不符合規定:沒有返回聲明

兼容解決方案:

var merged = arr.reduce(function(a, b) {
  return a.concat(b);
});

函數聲明不應在塊內進行

儘管大多數腳本引擎都支持塊內的功能聲明,但從瀏覽器到瀏覽器,實現之間是不一致的。

不兼容的代碼示例:

if (x) {
  function foo() {} //foo is hoisted in Chrome, Firefox and Safari, but not in Edge.
}

兼容解決方案:

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

元素類型選擇器不應與類選擇器一起使用

在類選擇器中使用元素類型比僅使用類選擇器要慢。

不兼容的代碼示例:

var $products = $("div.products");    // Noncompliant - slow

兼容解決方案:

var $products = $(".products");    // Compliant - fast

函數參數,捕獲的異常和foreach變量的初始值不應忽略

從功能體內分配參數在技術上是正確的,但它降低了代碼的可讀性,因爲開發人員無法在不經歷整個功能的情況下就無法確定是否正在訪問原始參數或某些臨時變量。而且,某些開發人員可能還希望函數參數的分配對調用者可見,但事實並非如此,這種缺乏可見性可能會使他們感到困惑。相反,所有參數,捕獲的異常和foreach參數都應視爲常量。

不兼容的代碼示例:

function MyClass(name, strings) {
  name = foo;                    // Noncompliant

  for (var str of strings) {
    str = "";  // Noncompliant
  }
}

帶有和不帶有“ new”的函數都不應被調用

創建新對象實例的構造函數只能用調用new。非構造函數一定不能。將這兩種用法混合使用可能會在運行時導致意外結果。

不兼容的代碼示例:

function getNum() {
  return 5;
}

function Num(numeric, alphabetic) {
  this.numeric = numeric;
  this.alphabetic = alphabetic;
}

var myFirstNum = getNum();
var my2ndNum = new getNum();  // Noncompliant. An empty object is returned, NOT 5

var myNumObj1 = new Num();
var myNumObj2 = Num();  // Noncompliant. undefined is returned, NOT an object

不應使用HTML樣式的註釋

HTML樣式的註釋不是EcmaScript規範的一部分,因此不應使用。

不兼容的代碼示例:

<!-- Noncompliant -->

兼容解決方案:

// Compliant
/* Compliant */

二進制運算符的兩側不應使用相同的表達式

在二元運算符的任一側使用相同的值幾乎總是一個錯誤。在邏輯運算符的情況下,它要麼是複製/粘貼錯誤, 要麼是浪費的代碼,應簡化。在按位運算符和大多數二進制數學運算符的情況下,在運算符的兩邊具有相同的值會產生可預測的結果,因此應簡化。

不兼容的代碼示例:

if (a == b && a == b) { // if the first one is true, the second one is too
  doX();
}
if (a > a) { // always false
  doW();
}

var j = 5 / 5; //always 1
var k = 5 - 5; //always 0

例外情況:針對其自身測試一個變量的特定情況對於而言是有效的測試,NaN因此將被忽略。

類似地,左移1到1在位掩碼的構造中很常見,並且被忽略。

此外,逗號運算符,和instanceof運算符會被忽略,因爲當使用有效時,存在用例。

if (f !== f) { // test for NaN value
  console.log("f is NaN");
}

var i = 1 << 1; // Compliant
var j = a << a; // Noncompliant

增量(++)和減量(-)運算符不應在方法調用中使用,或與表達式中的其他運算符混合使用

不建議在方法調用中或與其他算術運算符結合使用遞增和遞減運算符,因爲:

  • 這會嚴重損害代碼的可讀性。
  • 它在語句中引入了其他副作用,並可能導致不確定的行爲。
  • 與其他任何算術運算符隔離使用這些運算符會更安全。

不兼容的代碼示例:

u8a = ++u8b + u8c--;
foo = bar++ / 4;

兼容解決方案:

++u8b;
u8a = u8b + u8c;
u8c--;
foo = bar / 4;
bar++;

局部變量不應先聲明然後立即返回或拋出

僅聲明變量以立即返回或拋出該變量是一種不好的做法。

一些開發人員認爲,這種做法提高了代碼的可讀性,因爲它使他們能夠明確命名返回的內容。但是,此變量是內部實現細節,不會向方法的調用者公開。方法名稱應足以使調用者準確知道將返回什麼。

不兼容的代碼示例:

function computeDurationInMilliseconds() {
  var duration = (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;
  return duration;
}

兼容解決方案:

function computeDurationInMilliseconds() {
  return (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;
}

具有“null”或“undefined”值的變量的屬性不應訪問

爲變量分配undefinednull值時,它沒有屬性。無論如何,嘗試訪問此類變量的屬性都會TypeError導致,如果錯誤未在catch 塊中捕獲,則會導致腳本突然終止。但是catch最好不要完全避免這種情況。

不兼容的代碼示例:

if (x === undefined) {
  console.log(x.length); // Noncompliant; TypeError will be thrown
}

“ in”和“ instanceof”的結果應取反,而不是操作數

混合操作順序幾乎總是會產生意想不到的結果。

同樣,錯誤應用否定也會產生不良結果。例如考慮之間的差異!key in dict!(key in dict)。第一個在中尋找布爾值(!key)dict,另一個在尋找字符串並將結果取反。!obj instanceof SomeClass有同樣的問題。

否定in or instanceof運算符的左操作數時,此規則會引起問題。

不兼容的代碼示例:

if (!"prop" in myObj) {  // Noncompliant;  "in" operator is checking property "false"
  doTheThing();  // this block will be never executed
}

if (!foo instanceof MyClass) {  // Noncompliant; "!foo" returns a boolean, which is not an instance of anything
  doTheOtherThing();  // this block is never executed
}

兼容解決方案:

if (!("prop" in myObj)) {
  doTheThing();
}

if (!(foo instanceof MyClass)) {
  doTheOtherThing();
}

三元運算符不應嵌套

嵌套三元運算符會導致在你編寫代碼時看起來似乎很清晰的那種代碼,但是六個月後,將使維護人員(或更糟糕的是,你將來可能會)陷入困境並大罵。

不兼容的代碼示例:

function getTitle(p) {
  return p.gender == "male" ? "Mr. " : p.isMarried() ? "Mrs. " : "Miss ";  // Noncompliant
}

兼容解決方案:

function getTitle(p) {
  if (p.gender == "male") {
    return "Mr. ";
  }
  return p.isMarried() ? "Mrs. " : "Miss ";
}

不應使用全局“ this”對象

this對象之外使用關鍵字時,它指的是全局this對象,它與window標準網頁中的對象相同 。這樣的使用可能會使維護者感到困惑。相反,只需刪除this,或將其替換爲window;它將具有相同的效果,並且更具可讀性。

不兼容的代碼示例:

this.foo = 1;   // Noncompliant
console.log(this.foo); // Noncompliant

function MyObj() {
  this.foo = 1; // Compliant
}

MyObj.func1 = function() {
  if (this.foo == 1) { // Compliant
    // ...
  }
}

兼容解決方案:

foo = 1;
console.log(foo);

function MyObj() {
  this.foo = 1;
}

MyObj.func1 = function() {
  if (this.foo == 1) {
    // ...
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章