Por que “true” == true mostra falso em JavaScript?

90

MDC descreve o ==operador da seguinte maneira :

Se os dois operandos não forem do mesmo tipo, JavaScript os converte e aplica a comparação estrita. Se o operando for um número ou booleano, os operandos serão convertidos em números, se possível; else se qualquer operando for uma string, o outro operando é convertido em uma string, se possível.

Com isso em mente, eu avaliaria o "true" == trueseguinte:

  1. Eles são do mesmo tipo? Não
  2. O operando é um número ou booleano? sim
  3. Podemos converter ambos em um número? Não ( isNaN(Number("true")) // true)
  4. Qualquer um dos operandos é uma string? sim
  5. Podemos converter o outro operando em uma string? Sim ( String(true) === "true" // true)

Acabei com as strings "true"e "true", que deve avaliar como true, mas o JavaScript mostra falso.

O que eu perdi?

Isaac
fonte
Relevante: es5.github.com/#x11.9.1
zzzzBov
6
Com tanto JavaScript por aí, o mundo é um lugar assustador: if("true" == true) {console.log("yes")} else {console.log("no")}; if("true") {console.log("yes")} else {console.log("no")}---> "não sim"
user1068352
1
Devo dizer que estou surpreso, e é tão estúpido que isso aconteça. Mais uma razão para sempre sempre usar ===
BT
@ user1068352 verifique o caos :) dorey.github.io/JavaScript-Equality-Table
João Pimentel Ferreira

Respostas:

89

Porque "true"é convertido para NaN, enquanto trueé convertido para 1. Então eles são diferentes.

Como você relatou, ambos são convertidos em números, porque pelo menos truepodem ser (veja o comentário de Erik Reppen), e depois comparados.

MaxArt
fonte
Você pode me dizer quando o passo Can we convert both to a number?será falso então? Se par NaNfor um número, como essa etapa pode falhar?
Isaac
5
Qualquer um contra nenhum. Se ambos resultassem em NaN, eles mudariam para avaliação de string. Se apenas um pode ser convertido, ainda há uma comparação numérica.
Erik Reppen
2
Na verdade, existem alguns objetos estranhos em Javascript que se comportam de maneira bastante estranha. Por exemplo, documentos XML no IE <9 geram um erro quando você tenta convertê-los em números.
MaxArt
Você mesmo pode ver as conversões fazendo Number(true)eNumber('true')
Erik Reppen
11

O ==operador de comparação é definido no ECMA 5 como:

  1. Se Type (x) for Number e Type (y) for String,
    retorne o resultado da comparação x == ToNumber (y).
  2. Se Type (x) for String e Type (y) for Number,
    retorne o resultado da comparação ToNumber (x) == y.
  3. Se Type (x) for Boolean, retorne o resultado da comparação ToNumber (x) == y.
  4. Se Type (y) for Boolean, retorne o resultado da comparação x == ToNumber (y).

Portanto, "true" == true é avaliado como:

  1. "true" == ToNumber (true)   (via regra 7)
  2. "verdadeiro" == 1
  3. ToNumber ("true") == 1   (via regra 5)
  4. NaN == 1

===> falso

nobitavn94
fonte
3

De acordo com o algoritmo de comparação de igualdade abstrata

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

se um dos oprends for booleano e o outro não, boolean é o conversor para o número 0 ou 1. então true == "true"é falso.

Zohaib Ijaz
fonte
Eu deduzi certo da seguinte maneira? "true" == true torna-se "true" == 1 e depois torna-se "true" == "1" É por isso que eles retornam false?
vuquanghoang 01 de