• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Niejawna koercja w JS. Porównywanie wartości

Object Storage Arubacloud
+1 głos
1,401 wizyt
pytanie zadane 20 grudnia 2017 w JavaScript przez Artek Stary wyjadacz (11,800 p.)

Zastanawia mnie pewna rzecz. Po pierwsze rzućmy okiem na następujący kod.

if(" ")
  {
    console.log("1 warunek wszedł");
  }
else
  {
    console.log("1 warunek nie wszedł")
  }

Efekt takiego kodu w konsoli to: 1 warunek wszedł. Wniosek z tego taki, że " " czyli spacja została zamieniona na true. Czyli jak wyczytałem w książce mamy tu do czynienia z tzw. "niejawną koercją" - zamiana typu wartości. Na razie nic nadzwyczajnego. Ale spójrzmy na ten kod:

 if(true == " ")
   {
     console.log("2 warunek wszedł");
   }
   else
   {
    console.log("2 warunek nie wszedł");
   }

Jak się okazuje efektem wykonania takiego kodu jest : "2 warunek nie wszedł"

Wydaje się to być dziwne. Wcześniej spacja została zamieniona na true. Na chłopski rozum skoro wcześniej spacja została zamieniona na true to w tym wypadku też powinno tak być. Spacja zostałaby zamieniona na true i wtedy true równa się true i warunek zostaje spełniony. No ale tak się nie dzieje. Pytanie dlaczego. Dlaczego raz traktuje spację jako true a raz nie? A może zamienia true na "true" ? Jeżeli tak to jakie reguły rządzą wyborem wartości do koercji? Kto nie wierz niech sprawdzi.

https://codepen.io/anon/pen/rpLwrO?editors=1112

komentarz 20 grudnia 2017 przez lapacz.kornel Mądrala (6,930 p.)
edycja 20 grudnia 2017 przez lapacz.kornel

Jak zrobisz coś takiego 

true == new Boolean("  ")

lub

true == !!" "

czyli zamienisz '" "' na Boolean 

Boolean - a binary variable, having two possible values called “true” and “false.”.

to ci da  "2 warunek wszedł"

Edit:

Jak wpiszesz w konsoli jakiś string to ci go zwróci.  W if musi być true lub false więc konwertuje (?) to na Boolean. A warunek true == " " zwraca false więc nie ma czego konwertować (?). Jeśli się mylę proszę porawić...

komentarz 20 grudnia 2017 przez Artek Stary wyjadacz (11,800 p.)
To nie jest odpowiedź na moje pytanie. To w żaden sposób nie wyjaśnia mechanizmu działania języka.
komentarz 20 grudnia 2017 przez kubaapk Nałogowiec (44,270 p.)
Wrzuc sobie typeof " " w konsole i zobacz co Ci zwroci.
komentarz 20 grudnia 2017 przez lapacz.kornel Mądrala (6,930 p.)

Edit:

Jak wpiszesz w konsoli jakiś string to ci go zwróci.  W if musi być true lub false więc konwertuje (?) to na Boolean. A warunek true == " " zwraca false więc nie ma czego konwertować (?). Jeśli się mylę proszę porawić...

Jako że to nie do końca jest odpowiedź nie dalem tego jako odpowiedzi tylko jako komentarz  

komentarz 20 grudnia 2017 przez Artek Stary wyjadacz (11,800 p.)
typeof " " zwraca string, no ale co z tego?
komentarz 20 grudnia 2017 przez Artek Stary wyjadacz (11,800 p.)
Zgadzam się, że w if musi być true lub false. No to skoro w pierwszym przypadku zamienił" " czyli spację na true to dlaczego w drugim nie zamienił spacji na true?
komentarz 20 grudnia 2017 przez lapacz.kornel Mądrala (6,930 p.)
Bo niebyło po co. W pierwszym przypadku zamienił " " na true tylko dlatego że if zwrocił string a nie Boolean
komentarz 20 grudnia 2017 przez Artek Stary wyjadacz (11,800 p.)

Jak to nie było po co? Mamy dwa rodzaje wartości. String i Boolean. Aby móc je porównać musimy te wartości zamienić na ten sam typ. Operator luźnego porównania czyli == pozwala na niejawną konwersję wartości. Czyli jeżeli mamy coś takiego.

if(45 == "45")
   {
     console.log("warunek wszedł");
   }
   else
   {
    console.log("warunek nie wszedł");
   }

W if'ie dojdzie do niejawnej koercji(zamiany typu wartości) jednej z wartości czyli podejrzewam, że zamieni string na number i wtedy porówna i warunek wejdzie. Tak samo musi zrobić w 2 przykładzie jak pokazałem na początku. Nie może porównywać dwóch typów wartości bez zamiany(koercji). Czy może? Na chłopski rozum to bez sensu, no bynajmniej jak dla mnie.

komentarz 20 grudnia 2017 przez lapacz.kornel Mądrala (6,930 p.)
W drugim przypadku do koercji nie dojdzie. true nie jest rowne " ".

2 odpowiedzi

+1 głos
odpowiedź 20 grudnia 2017 przez Comandeer Guru (601,450 p.)
wybrane 20 grudnia 2017 przez Artek
 
Najlepsza

Koercja najpierw sprowadza obydwie porównywane zmienne do jednego typu, a następnie dokonuje porównania. W tym wypadku obydwie wartości są sprowadzane do typu Number i dopiero wtedy porównywane. Stąd true jest sprowadzane do 1, a ' ' do 0 – ergo: wartości nie są równe.

Przy okazji warto zauważyć, że wewnątrz if są wykorzystywane inne zasady (wartość wewnątrz jest rzutowana bezpośrednio na boolean).

komentarz 20 grudnia 2017 przez Artek Stary wyjadacz (11,800 p.)

Mam parę pytań w takim razie. W artykule, którym podałeś napisano:

Coercion is possible only via == (eqeq) operator

Tymczasem w mojej książce pod tytułem : "Tajniki języka JavaScript" napisano:

JavaScript oferuje kilka różnych możliwości w zakresie wymuszania koercji pomiędzy typami Na przykład:

var a = 42;

var b = Number(a); 

Użycie funkcji Number jest przykładem wyraźnej koercji dowolnego typu na typ Number

Jeżeli wierzyć książce a z tego co wiem jest wiarygodna to autor artykułu się myli bynajmniej w tej kwestii. No, ale to tak na marginesie.

Analizując dostarczone przez Ciebie materiały doszedłem do następujących wniosków.

Jakakolwiek wartość wewnątrz if'a zostanie potraktowana jako true za wyjątkiem następujących :

false, null, undefined, 0, "", '', NaN

Oto co wydarzyło się w przykładzie numer 2 - przytoczonym przeze mnie.

Najpierw to

  1. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y: false == 0 and true == 1 but true != 2 

Czyli true zostało zamienione na 1.

No o.k Czyli teraz mamy taki warunek 

1 == " "

I czytając dalej przytoczony artykuł : 

  1. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y): 2 == "2"

A tak się składa, że 

Number(" ")

Zwraca zero.

Czyli ostatecznie nasz warunek wygląda tak:

1 == 0

Co jest oczywiście fałszem i zgadza się z tym co dostajemy na wyjściu. Dobrze to obczaiłem?

komentarz 20 grudnia 2017 przez Comandeer Guru (601,450 p.)

Jeżeli wierzyć książce a z tego co wiem jest wiarygodna to autor artykułu się myli bynajmniej w tej kwestii.

Wypada odróżnić niejawną koercję (czyli to, o czym mówimy) od tego, co jest opisane w książce – jawnej koercji (czyli inaczej mówiąc rzutowania).

 Dobrze to obczaiłem?

Tak. 

komentarz 20 grudnia 2017 przez Artek Stary wyjadacz (11,800 p.)
Dzięki bardzo za pomoc. Commander jak zwykle sypie jak z rękawa przydatnymi artykułami :D
+1 głos
odpowiedź 19 sierpnia 2019 przez pog(r)ubiony Początkujący (340 p.)
komentarz 19 sierpnia 2019 przez Artek Stary wyjadacz (11,800 p.)
Fajne :)

Podobne pytania

0 głosów
1 odpowiedź 860 wizyt
+1 głos
1 odpowiedź 248 wizyt
0 głosów
2 odpowiedzi 2,038 wizyt

92,575 zapytań

141,424 odpowiedzi

319,649 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...