使用 else if 处理 ESLint 规则

Fallowing ESLint rules with else if

我有这个代码else/if代码

       if (_.has($scope.item, 'comment_id')) {
          track(one);
        } else if (_.has($scope.item, 'post_id')) {
          track(two);
        } else {
          if ($scope.followers) {
            track(three);
          } else {
            track(four);
          }
        }

但是 ESlint 希望我把它变成这个

        if (_.has($scope.item, 'comment_id')) {
          track(one);
        } else if (_.has($scope.item, 'post_id')) {
          track(two);
        } else if ($scope.followers) {
          track(three);
        } else {
          track(four);
        }

它们是一回事吗?

是的,它们是等价的。 ESLint 足够聪明,可以检测到这一点并因此提出建议。原因是您在 if/else 构造中实际上只有四个选择 - 当代码不匹配前两个条件中的任何一个时,它将始终执行外部

else {
  if ($scope.followers) {
    track(three);
  } else {
    track(four);
  }
}

这只会导致两种情况之一发生。将 if ($scope.followers) 提取为 else if 遵循完全相同的逻辑路径。

这可以很容易地通过抽象出条件并生成一个真值 table,然后检查结果来证明。它可以在纸上完成,但由于您已经有了代码,因此也很容易将其制作为代码:

function nested(a, b, c) {
  if (a) {
    return "track(one)";
  } else if (b) {
    return "track(two)";
  } else {
    if (c) {
      return "track(three)";
    } else {
      return "track(four)";
    }
  }
}

function chained(a, b, c) {
  if (a) {
    return "track(one)";
  } else if (b) {
    return "track(two)";
  } else if (c) {
    return "track(three)";
  } else {
    return "track(four)";
  }
}

const truthTable = [
  [false, false, false],
  [false, false, true ],
  [false, true , false],
  [false, true , true ],
  [true , false, false],
  [true , false, true ],
  [true , true , false],
  [true , true , true ],
];

for(const [a, b, c] of truthTable) {
  const nestedResult = nested(a, b, c);
  console.log(`called nested() with 
  a=${a}
  b=${b}
  c=${c}
  result: ${nestedResult}`);
  
  const chainedResult = chained(a, b, c);
  console.log(`called nested() with 
  a=${a}
  b=${b}
  c=${c}
  result: ${chainedResult}`);
  
  console.log(`matching results?: ${nestedResult === chainedResult}`);
  
  console.log(`------------------------`);
}

或者,您可以生成真实的事实 table 以可视化结果:

function nested(a, b, c) {
  if (a) {
    return "track(one)";
  } else if (b) {
    return "track(two)";
  } else {
    if (c) {
      return "track(three)";
    } else {
      return "track(four)";
    }
  }
}

function chained(a, b, c) {
  if (a) {
    return "track(one)";
  } else if (b) {
    return "track(two)";
  } else if (c) {
    return "track(three)";
  } else {
    return "track(four)";
  }
}

const truthTable = [
  [false, false, false],
  [false, false, true ],
  [false, true , false],
  [false, true , true ],
  [true , false, false],
  [true , false, true ],
  [true , true , false],
  [true , true , true ],
];

const enrich = truthTable
  .map(row => row.concat(nested(...row), chained(...row))) //add the results of the two calls
  .map(row => row.concat(row[row.length-1] === row[row.length-2])) //compare the last two

const table = document.querySelector("table");
for (const rowData of enrich) {
  const newRow = table.insertRow(-1);
  for (const rowValue of rowData) {
    const cell = newRow.insertCell(-1);
    cell.textContent = rowValue;
  }
}
table {
  border-collapse: collapse;
}

table, th, td {
  border: 1px solid black;
}
<table>
  <tr>
    <th>a</th>
    <th>b</th>
    <th>c</th>
    <th>nested result</th>
    <th>chained result</th>
    <th>results equal</th>
  </tr>
</table>