Чому “true” == true показує false у JavaScript?


89

MDC описує ==оператора наступним чином :

Якщо два операнди не одного типу, JavaScript перетворює операнди, тоді застосовується суворе порівняння. Якщо будь-який операнд є числом або булевим значенням, операнди перетворюються в числа, якщо це можливо; в іншому випадку, якщо будь-який операнд є рядком, інший операнд перетворюється у рядок, якщо це можливо.

З огляду на це, я б оцінив "true" == trueнаступне:

  1. Вони однотипні? Немає
  2. Чи операнд - це число, або логічне значення? Так
  3. Чи можемо ми перетворити обидва на число? Ні ( isNaN(Number("true")) // true)
  4. Чи є операнд рядком? Так
  5. Чи можемо ми перетворити інший операнд у рядок? Так ( String(true) === "true" // true)

Я закінчив із рядками "true"і "true", які повинні оцінювати true, але JavaScript показує false.

Що я пропустив?


Відповідно: es5.github.com/#x11.9.1
zzzzBov

6
З такою кількістю JavaScript навколо, світ - це страшне місце: if("true" == true) {console.log("yes")} else {console.log("no")}; if("true") {console.log("yes")} else {console.log("no")}---> "ні так"
user1068352

1
Потрібно сказати, що мене дивують, і це дуже дурно, що це трапляється. Ще одна причина завжди завжди завжди використовувати ===
BT

Відповіді:


89

Тому що "true"перетворюється на NaN, тоді trueяк перетворюється на1 . Тож вони різняться.

Як і ви повідомляли, обидва перетворюються в числа, тому що принаймні trueможуть бути (див. Коментар Еріка Реппена), а потім порівнюються.


Чи можете ви сказати мені, коли тоді крок Can we convert both to a number?колись буде хибним? Якщо парне NaNчисло, то як цей крок може колись провалитися?
Ісаак

5
Або проти жодного. Якщо обидва результати призведуть до NaN, вони перейдуть на оцінку рядків. Якщо можна перетворити лише одну, все ще існує порівняння чисел.
Ерік Реппен

2
Насправді в Javascript є якісь дивні об’єкти, які поводяться досить дивно. Наприклад, XML-документи в IE <9 викликають помилку під час спроби перетворити їх у числа.
MaxArt

Ви можете побачити перетворення самостійно, виконавши Number(true)іNumber('true')
Ерік Реппен

10

Оператор ==порівняння визначений у ECMA 5 як:

  1. Якщо тип (x) - число, а тип (y) - рядок,
    поверніть результат порівняння x == ToNumber (y).
  2. Якщо Type (x) - String, а Type (y) - Number,
    поверніть результат порівняння ToNumber (x) == y.
  3. Якщо тип (x) є логічним, поверніть результат порівняння ToNumber (x) == y.
  4. Якщо тип (y) є логічним, поверніть результат порівняння x == ToNumber (y).

Отже, "true" == true оцінюється як:

  1. "true" == ToNumber (true)   (за правилом 7)
  2. "true" == 1
  3. ToNumber ("true") == 1   (за правилом 5)
  4. NaN == 1

===> невірно


3

Відповідно до алгоритму порівняння абстрактних рівності

http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

якщо один із виправлень є логічним значенням, а інший - ні, логічний перетворювач є перетворювачем на число 0 або 1., тож true == "true"неправда.


Чи я зробив висновок наступним чином? "true" == true стає "true" == 1, а потім стає "true" == "1" Ось чому вони повертають false?
vuquanghoang
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.