【问题标题】:Fallowing ESLint rules with else if用 else if 放宽 ESLint 规则
【发布时间】:2021-01-31 02:45:50
【问题描述】:

我有这个代码 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);
        }

它们是一样的吗?

【问题讨论】:

  • 是的,为什么它们会有所不同?如果其他人失败,您只会陷入外部else。与链接另一个 else/if 相同。
  • else + if 实际上是一个else ifelse + else 仍然是 else

标签: javascript angularjs eslint


【解决方案1】:

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

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

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

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

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(`------------------------`);
}

或者,您可以生成一个实际的真值表来可视化结果:

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>

【讨论】:

    猜你喜欢
    • 2018-11-15
    • 2019-04-16
    • 2019-05-30
    • 2021-10-16
    • 2018-02-19
    • 1970-01-01
    • 2023-03-08
    • 2020-08-04
    • 2016-04-14
    相关资源
    最近更新 更多