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?



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

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.


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


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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.