# 爱彼迎编码规范

# parison Operators & Equality

  • 15.1 Use === and !== over == and !=. eslint: eqeqeq

  • 15.2 Conditional statements such as the if statement evaluate their expression using coercion with the ToBoolean abstract method and always follow these simple rules:

    • Objects evaluate to true
    • Undefined evaluates to false
    • Null evaluates to false
    • Booleans evaluate to the value of the boolean
    • Numbers evaluate to false if +0, -0, or NaN, otherwise true
    • Strings evaluate to false if an empty string '', otherwise true
    if ([0] && []) {
      // true
      // an array (even an empty one) is an object, objects will evaluate to true
    }
    
  • 15.3 Use shortcuts for booleans, but explicit comparisons for strings and numbers.

    // bad
    if (isValid === true) {
      // ...
    }
    
    // good
    if (isValid) {
      // ...
    }
    
    // bad
    if (name) {
      // ...
    }
    
    // good
    if (name !== '') {
      // ...
    }
    
    // bad
    if (collection.length) {
      // ...
    }
    
    // good
    if (collection.length > 0) {
      // ...
    }
    
  • 15.4 For more information see Truth Equality and JavaScript by Angus Croll.

  • 15.5 Use braces to create blocks in case and default clauses that contain lexical declarations (e.g. let, const, function, and class). eslint: no-case-declarations

    Why? Lexical declarations are visible in the entire switch block but only get initialized when assigned, which only happens when its case is reached. This causes problems when multiple case clauses attempt to define the same thing.

    使用花括号包围代码:With ECMAScript 2015 (ES6) support made available in most modern browsers, there will be cases where you would want to use let and const statements to declare block-scoped variables.

    // bad
    switch (foo) {
      case 1:
        let x = 1
        break
      case 2:
        const y = 2
        break
      case 3:
        function f() {
          // ...
        }
        break
      default:
        class C {}
    }
    
    // good
    switch (foo) {
      case 1: {
        let x = 1
        break
      }
      case 2: {
        const y = 2
        break
      }
      case 3: {
        function f() {
          // ...
        }
        break
      }
      case 4:
        bar()
        break
      default: {
        class C {}
      }
    }
    
  • 15.6 Ternaries should not be nested and generally be single line expressions. eslint: no-nested-ternary

    // bad
    const foo = maybe1 > maybe2 ? 'bar' : value1 > value2 ? 'baz' : null
    
    // split into 2 separated ternary expressions
    const maybeNull = value1 > value2 ? 'baz' : null
    
    // better
    const foo = maybe1 > maybe2 ? 'bar' : maybeNull
    
    // best
    const foo = maybe1 > maybe2 ? 'bar' : maybeNull
    
  • 15.7 Avoid unneeded ternary statements. eslint: no-unneeded-ternary

    // bad
    const foo = a ? a : b
    const bar = c ? true : false
    const baz = c ? false : true
    
    // good
    const foo = a || b
    const bar = !!c
    const baz = !c
    
  • 15.8 When mixing operators, enclose them in parentheses. The only exception is the standard arithmetic operators: +, -, and ** since their precedence is broadly understood. We recommend enclosing / and * in parentheses because their precedence can be ambiguous when they are mixed. eslint: no-mixed-operators

    Why? This improves readability and clarifies the developer’s intention.

    // bad
    const foo = (a && b < 0) || c > 0 || d + 1 === 0
    
    // bad
    const bar = a ** b - (5 % d)
    
    // bad
    // one may be confused into thinking (a || b) && c
    if (a || (b && c)) {
      return d
    }
    
    // bad
    const bar = a + (b / c) * d
    
    // good
    const foo = (a && b < 0) || c > 0 || d + 1 === 0
    
    // good
    const bar = a ** b - (5 % d)
    
    // good
    if (a || (b && c)) {
      return d
    }
    
    // good
    const bar = a + (b / c) * d
    
Last Updated: Monday, May 25, 2020 10:20 PM