【问题标题】:Odd behavior with else if statement (javascript)else if 语句的奇怪行为(javascript)
【发布时间】:2014-12-08 09:11:13
【问题描述】:

据我所知,代码工作正常,但是当添加或编辑更多信息时,if else 语句开始表现异常。它正在正确读取百分比值,但没有返回正确的字母字符串。

var total = function (){
    var earned = 0;

     for(i = 0; i < Assignments.length; i++){
         earned += parseInt(Assignments[i].earned);
     }
     var possible = 0;

     for(i = 0; i < Assignments.length; i++){
         possible += parseInt(Assignments[i].possible);
     }
     var percent = (Math.floor((earned/possible) * 100));

     console.log(percent);

  //grade letter

      if (percent >= 90){
         grade.innerHTML = '';
         grade.innerHTML = 'A ' + percent + '%';
      } else if (percent <= 89 && 80 >= percent){
         grade.innerHTML = '';
         grade.innerHTML = 'B ' + percent + '%';
      } else if (percent <= 79 && 70 >= percent){
         grade.innerHTML = '';
         grade.innerHTML = 'C ' + percent + '%';
      } else if (percent <= 69 && 60 >= percent){
         grade.innerHTML = '';
         grade.innerHTML = 'D ' + percent + '%';
      } else if(percent <= 59 && 0 >= percent){
         grade.innerHTML = '';
         grade.innerHTML = 'F ' + percent + '%';
      } else {grade.innerHTML = '';}



};

经过几次输入后,它会返回如下内容:

我认为可能是 else if 语句相互冲突,但老实说,我不知道为什么会这样。

【问题讨论】:

  • 有什么冲突?您不想返回什么?它究竟是如何出错的?
  • 为什么不使用 switch 语句?它比许多 if/else 块更容易阅读。 w3schools.com/js/js_switch.asp
  • @WhiteBr0wnie_24 如何使用带数字范围的开关?
  • 我同意,您最好使用开关,这通常是开关的工作。与 switch 相比,任何 if/else 解决方法都非常可耻:)
  • @Juhana 等。 al.:虽然 可能 在 JavaScript 中为此使用 switchstackoverflow.com/a/17145931/157247,参见 #3),但它只是冗长的 else if

标签: javascript if-statement return-value comparison-operators


【解决方案1】:

您在else ifs 中进行了比较,您使用的是70 &gt;= percent 而不是percent &gt;= 70(等等)。

另外,如果您要为其分配其他内容,则没有理由将 '' 分配给 innerHTML,也没有理由重申上限(percent &lt;= 89 等),因为您是使用else if,所以percent &gt;= 90 分支已经被跟随。重申它们也是一个维护问题(您将更改一个但忘记更改另一个)。

所以:

if (percent >= 90) {
    grade.innerHTML = 'A ' + percent + '%';
} else if (percent >= 80) {
    grade.innerHTML = 'B ' + percent + '%';
} else if (percent >= 70) {
    grade.innerHTML = 'C ' + percent + '%';
} else if (percent >= 60) {
    grade.innerHTML = 'D ' + percent + '%';
} else if (percent >= 0) {
    grade.innerHTML = 'F ' + percent + '%';
} else {
    grade.innerHTML = '';
}

当然,您也可以使用地图,因为您的年级界限可以被 10 整除:

// Somewhere central
var grades = {
    6: 'D',
    7: 'C',
    8: 'B',
    9: 'A',
    10: 'A'
};

// ...then simply:
if (percent >= 0) {
    grade.innerHTML = (grades[Math.floor(percent / 10)] || 'F') + ' ' + percent + '%';
} else {
    grade.innerHTML = "Less than 0?!";
}

var grades = {
    6: 'D',
    7: 'C',
    8: 'B',
    9: 'A',
    10: 'A'
};

function showGrade(percent) {
  var grade;
  if (percent >= 0) {
    grade = (grades[Math.floor(percent / 10)] || 'F') + ' ' + percent + '%';
  } else {
    grade = "Less than 0?!";
  }
  snippet.log(grade);
}

var n;
for (n = 0; n <= 100; ++n) {
  showGrade(n);
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

【讨论】:

  • “地图解决方案”是最好的恕我直言。
【解决方案2】:

If-Else 条件范围看起来不对,试试这个代码...

var total = function (){
var earned = 0, possible = 0;
for(i = 0; i < Assignments.length; i++){
     possible += parseInt(Assignments[i].possible);
     earned += parseInt(Assignments[i].earned);
 }
 var percent = (Math.floor((earned/possible) * 100));

 console.log(percent);

  //grade letter

  if (percent >= 90){
     grade.innerHTML = 'A ' + percent + '%';
  } else if (percent >= 80 && percent <= 89){
     grade.innerHTML = 'B ' + percent + '%';
  } else if (percent >= 70 && percent <= 79){
     grade.innerHTML = 'C ' + percent + '%';
  } else if (percent >= 60 && percent <= 69){
     grade.innerHTML = 'D ' + percent + '%';
  } else if(percent >= 0 && percent <= 59){
     grade.innerHTML = 'F ' + percent + '%';
  } else {grade.innerHTML = '';}
};

虽然我已经优化了一些代码,不需要2个循环,你可以在一个循环中对earnedpossible变量求和,在元素中赋值时不需要.innerHTML = ''

【讨论】:

    【解决方案3】:

    我发现一篇关于使用不同方法比较事物的效率的好帖子。我仍然建议使用 switch-block 而不是 if/else,但它在技术上并不比您的解决方案好,但我认为它更易于阅读。这是一个代码sn-p:

    switch (true) {
    case (0 <= val &&  val < 1000): /* do something */ break;
    case (1000 <= val &&  val < 2000): /* do something */ break;
    ...
    case (29000 <= val &&  val < 30000): /* do something */ break;
    }
    

    取自这篇文章。还有一个有趣的表(在第一个答案中) Switch statement for greater-than/less-than 以及制作这项工作的不同方法。我知道这实际上不是您答案的解决方案,但如果您需要添加更多 if/else 并且正在做一些带有值的巨大列表,它可能会派上用场。

    【讨论】:

    • 重复边界会导致维护错误。但是你可以做同样的事情而不重复边界,在JavaScript中switch案例被评估顺序并且只有第一个匹配的一个被执行(就像else if )。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 2015-05-16
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多