Dlaczego „true” == true oznacza fałsz w JavaScript?

89

MDC opisuje ==operatora w następujący sposób :

Jeśli dwa operandy nie są tego samego typu, JavaScript konwertuje operandy, a następnie stosuje ścisłe porównanie. Jeśli którykolwiek z operandów jest liczbą lub wartością logiczną, operandy są konwertowane na liczby, jeśli to możliwe; w przeciwnym razie, jeśli którykolwiek operand jest łańcuchem, drugi operand jest konwertowany na łańcuch, jeśli to możliwe.

Mając to na uwadze, oceniłbym "true" == truenastępująco:

  1. Czy są tego samego typu? Nie
  2. Czy operand jest liczbą czy wartością logiczną? tak
  3. Czy możemy zamienić oba na liczbę? Nie ( isNaN(Number("true")) // true)
  4. Czy któryś z operandów jest łańcuchem? tak
  5. Czy możemy zamienić inny operand na łańcuch? Tak ( String(true) === "true" // true)

Skończyło się na ciągach "true"i "true", co powinno dać wynik true, ale JavaScript pokazuje fałsz.

Co przegapiłem?

Izaak
źródło
Trafne: es5.github.com/#x11.9.1
zzzzBov,
6
Przy tak dużej if("true" == true) {console.log("yes")} else {console.log("no")}; if("true") {console.log("yes")} else {console.log("no")}
liczbie
1
Muszę powiedzieć, że jestem zaskoczony, a to jest takie głupie, że tak się dzieje. Jeszcze jeden powód, aby zawsze zawsze używać ===
BT
@ user1068352 sprawdź chaos :) dorey.github.io/JavaScript-Equality-Table
João Pimentel Ferreira

Odpowiedzi:

89

Ponieważ "true"jest konwertowany na NaN, while truejest konwertowany na 1. Więc się różnią.

Tak jak donosiłeś, oba są konwertowane na liczby, ponieważ przynajmniej truemożna je (zobacz komentarz Erika Reppena), a następnie porównywane.

MaxArt
źródło
Czy możesz mi powiedzieć, kiedy ten krok Can we convert both to a number?będzie kiedykolwiek fałszywy? Jeśli nawet NaNjest liczbą, jak ten krok może się nie powieść?
Izaak
5
Albo kontra żadne. Gdyby oba dały wynik NaN, przełączyliby się na ocenę łańcucha. Jeśli można przekonwertować tylko jeden, nadal istnieje porównanie liczb.
Erik Reppen
2
W Javascript jest kilka dziwnych obiektów, które zachowują się dość dziwnie. Na przykład dokumenty XML w IE <9 generują błąd przy próbie konwersji ich na liczby.
MaxArt
Możesz sam zobaczyć konwersje, robiąc Number(true)iNumber('true')
Erik Reppen,
10

==Operator porównania jest zdefiniowana w ECMA 5 jako:

  1. Jeśli Type (x) to Number, a Type (y) to String,
    zwróć wynik porównania x == ToNumber (y).
  2. Jeśli Type (x) to String, a Type (y) to Number,
    zwróć wynik porównania ToNumber (x) == y.
  3. Jeśli Type (x) jest Boolean, zwróć wynik porównania ToNumber (x) == y.
  4. Jeśli Type (y) jest Boolean, zwróć wynik porównania x == ToNumber (y).

Tak więc "true" == true jest oceniane jako:

  1. "true" == ToNumber (true)   (za pomocą reguły 7)
  2. „prawda” == 1
  3. ToNumber („true”) == 1   (za pomocą reguły 5)
  4. NaN == 1

===> fałsz

nobitavn94
źródło
3

Zgodnie z algorytmem porównawczym abstrakcyjnej równości

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

jeśli jeden z oprendów jest wartością logiczną, a inny nie, to wartość logiczna jest konwertowana na liczbę 0 lub 1. więc true == "true"jest fałszem.

Zohaib Ijaz
źródło
Czy doszedłem do wniosku w następujący sposób? „true” == true staje się „true” == 1, a następnie staje się „true” == „1” Dlatego zwracają fałsz?
vuquanghoang