Почему Javascript приравнивает 5 == 8 к истине? - PullRequest
10 голосов
/ 11 июня 2019

Итак, у меня есть 2 флажка:

var statusList = [];
function updateStatusString(x) {
    if (statusList != null) {
        if (statusList.length > 0) {
            for (var i = 0; i < statusList.length; i++) {
                if (parseInt(statusList[i]) == parseInt(x)) {
                    statusList[i] = 123;
                } else {
                    statusList.push(x);
                }
            }
        } else {
            statusList.push(x);
        }
    }
    alert(statusList);
}
<label>&nbsp;<input type="checkbox" name="Active" value="5" onchange=updateStatusString("5")>&nbsp;"Active"</label>
<label>&nbsp;<input type="checkbox" name="NonActive" value="8" onchange=updateStatusString("8")>&nbsp;"Active"</label>

Когда я нажимаю флажок, он добавляет его в список JavaScript, если он уже есть в списке, я хочу перезаписать его другим значением (123 в этом примере).

Но когда я щелкаю по второму (не имеет значения порядок, по каким-то причинам 2-й элемент всегда равен 123.

Где, как я и ожидал, если бы я щелкнул верхний флажок, это был бы список, содержащий '5', затем щелкнув по второму флажку, я бы ожидал 5,8, но он предупреждает как 5,123, не действительно понимаешь, почему он делает это, поскольку 5==8 ложно ... есть идеи?

Обновлен алгоритм для устранения основной проблемы:

На случай, если кто-нибудь найдет это полезным, я изменил алгоритм на лучшую альтернативу:

var statusList = [];
function updateStatusString(x) {
    if (statusList.length > 0) {
        if (statusList.includes(x)) {
            var idx = statusList.indexOf(x);
            if (idx != -1) {
                statusList.splice(idx, 1);
            }
        }
        else {
            statusList.push(x);
        }
    } else {
        statusList.push(x);
    }
    alert(statusList);
}

Ответы [ 3 ]

10 голосов
/ 11 июня 2019

первая итерация:

, так как список статусов пуст, вы добавляете в него 5,

вторая итерация:

statulsList = [5]

вы добавляете 8, так что теперь значение statusList равно [5,8], что также означает, что длина равна 2,

поэтому у нас есть третья итерация, которая в данном случае 8 === 8.

если вы хотите изменить его, сохраните длину списка состояний перед добавлением другого элемента в список.

var statusList = [];
function updateStatusString(x) {
    if (statusList != null) {
        if (statusList.length > 0) {
           var lengthStat = statusList.length;
            for (var i = 0; i < lengthStat; i++) {
                if (parseInt(statusList[i]) == parseInt(x)) {
                    statusList[i] = 123;
                } else {
                    if(! (statusList.indexOf(x) != -1))
                        statusList.push(x);
                }
            }
        } else {
            statusList.push(x);
        }
    }
    alert(statusList);
}
<label>&nbsp;<input type="checkbox" name="Active" value="5" onchange=updateStatusString("5")>&nbsp;"Active"</label>
<label>&nbsp;<input type="checkbox" name="NonActive" value="8" onchange=updateStatusString("8")>&nbsp;"Active"</label>
7 голосов
/ 11 июня 2019

Потому что вы перебираете statusList.На первой итерации вы проверяете, если 5 == 8, затем перемещаетесь к другой части и вставляете 8 в statusList.Ваш список статусов = = [5, 8].Для следующей итерации это становится истинным statuslist[i] будет 8 и 8 === 8, и ваше утверждение - statusList[i] = 123; заменит последнее вставленное значение 8 на 123.Следовательно, ваш массив statusList будет иметь ["5", 123].

var statusList = [];

function updateStatusString(x) {
  const input = parseInt(x);
  if (statusList != null) {
    if (statusList.includes(input)) {
      const idx = statusList.indexOf(input);
      statusList[idx] = 123;
    } else {
      statusList.push(input);
    }
    alert(statusList);
  }
}
<label>&nbsp;<input type="checkbox" name="Active" value="5" onchange=updateStatusString("5")>&nbsp;"Active"</label>

<label>&nbsp;<input type="checkbox" name="NonActive" value="8" onchange=updateStatusString("8")>&nbsp;"Active"</label>
3 голосов
/ 11 июня 2019

Похоже, что цикл был причиной вашей проблемы.

  1. Вы проверяли наличие x, которое в первом цикле было ложным
  2. Вы выдвинули его в массив
  3. Второй цикл, он существовал и был заменен на 123

Вы можете значительно упростить свой код, удалив одну из проверок if и используя array.prototype.include вместо зацикливания и проверки равенства.

Редактировать: Добавлен третий вход, чтобы продемонстрировать добавление 123 .

var statusList = [];
function updateStatusString(x) {
    if (statusList != null) {
      if (statusList.includes(x)) {
          statusList[statusList.indexOf(x)] = 123;
      } else {
          statusList.push(x);
      }
    }
    
    alert(statusList);
}
<label>&nbsp;<input type="checkbox" name="Active" value="5" onchange=updateStatusString("5")>&nbsp;"Active"</label>
<label>&nbsp;<input type="checkbox" name="NonActive" value="8" onchange=updateStatusString("8")>&nbsp;"Active"</label>
<label>&nbsp;<input type="checkbox" name="NonActive" value="8" onchange=updateStatusString("5")>&nbsp;"Active"</label>
...