== vs ===, czyli o koercji typów w JavaScript
Pierwszy odcinek z serii zrozumieć JavaScript będzie o operatorach? Tak, głównie o tym pierwszym, czyli podwójnym.
Nie jest to odcinek stricte o koercji typów, bo omawiam je na konkretnym przykładzie, na przykładnie operatora „==”. Ale to wystarczy żeby załapać zasadę działania tego mechanizmu.
Chciałem, żeby ten odcinek miał max. 10 minut… wyszło ponad 20 a wydaje mi się, że mówiłem zwięźle. Myślę, że to najlepszy dowód, że zwykłe porównanie operatorów wcale nie jest takie proste!
== vs ===
Mówiąc prostym językiem jaka jest różnica pomiędzy tymi operatorami? Ten potrójny jest dokładniejszy. Natomiast ten podwójny jest mniej dokładny.
Potrójny operator porównania … === …
Teraz trochę dokładniej. Potrójny operator sprawdza czy wartości po obu stronach są IDENTYCZNE!
Identyczne to znaczy czy ich wartość się zgadza, np. czy to jest 5, czy 4, czy ’hello’, oraz czy zgadza się ich typ, czyli czy jest to tekst, liczba czy boolean.
'2' === 2 // false
2 === 2 // true
Pierwszy przykład zwróci false, ponieważ ’2′ jest stringiem, czyli tekstem bo jest w cudzysłowie. Natomiast drugi parametr 2 jest typu number, czyli jest liczbą. Wynika z tego, że oba parametry nie są IDENTYCZNE. W drugim oba parametry mają taką samą wartość (2) oraz są tego samego typu (number), mówiąc prościej – są identyczne.
Podwójny operator porównania … == …
Tutaj zaczyna się dziać trochę magii. W podwójnym operatorze porównania JS zaczyna trochę myśleć „samodzielnie”. Próbuje pomóc i w kilku krokach zmienia typy parametrów na takie, aby na końcu zwrócić true (o ile się da).
Np. jeżeli mamy '2′ == 2 to JS zmieni typ pierwszego parametru na number. Sam możesz to zrobić w konsoli przeglądarki, wpisz Number(’2′). Wtedy kolejny krok wygląda już tak 2 == 2. Jeśli parametry są tego samego typu (oba są typu number) to następuje kolejny krok, czyli porównania potrójne 2 === 2, a to wiemy już, że zwróci true, prawda?
Koercja typów
Nie działa jednak kompletnie chaotycznie, chociaż na pierwszy rzut oka może się tak wydawać. Proces zmiany typu parametru nazywany jest koercją typów. Trudne słowo, które ma proste znaczenie: zmiana typu wartości na inny typ.
W podwójnym operatorze zmiana tych typów następuje wg ściśle określonych 10 króków:
- Jeśli oba parametry są tego samego typu porównaj je jeszcze raz potrójnym operatorem … === …
- Jeśli pierwszy jest null a drugi undefined, zwróć true. To trzeba zapamiętać.
- Odwrotność drugiego. Pierwszy to undefined, drugi null. Jak można się domyśleć, także zwróci true.
- Jeśli pierwszy jest number a drugi string. Stara się zmienić tekst na liczbę (w poprzednim akapicie wspomniałem jak można to zrobić). Następnie powtarza wszystkie kroki od początku.
- Odwrotność czwartego. Czyli pierwszy to string a drugi number. Zmienia typ stringu na number i powtarza wszystkie kroki.
- Jeśli pierwszy jest boolen a drugi czymkolwiek. Stara się zmienić boolean na number i powtarza wszystkie kroki (Number(true) = 1, Number(false) = 0).
- Odwrotność szóstego.
- Jeśli pierwszy jest wartością prymitywną (string, number, symbol) a drugi obiektem. Stara się zmienic obiekt to wartości prymitywnej i powtarza wszystkie kroki. Jak zmenić
- Odwrotność ósmego.
- Jeżeli żaden z poprzednich punktów nie jest naszym przypadkiem, zwóć false.
Powyższe 10 kroków to jedna iteracja, czyli jedno powtórzenie. Tych powtórzeń będzie tyle, aż w końcu dostaniemy true albo false. Ot, cała magia.
Kilka przykładów:
'2' == 2 // krok 5, ponieważ pierwszy parametr to string, drugi to number
2 == 2 // krok 1, poniważ oba parametry są tego samego typu (number)
2 === 2 // zwraca true, koniec koercji
null == undefinied // krok 2, zwróci true, koniec porównania
[] == 0 // krok 9, ponieważ pierwszy parametr to obiekt, następuje zmiana tablicy w wartość prymitywną (w tym przypadku w pusty string)
'' == 0 // krok 5, ponieważ pierwsza wartosć to string, druga to number, następuje zmiana stringu na number
0 == 0 // krok 1, ponieważ oba parametry są już tego samego typu
0 === 0 // zwraca true, koniec koercji
Po więcej przykładów i dokładniejsze wytłumaczenie zapraszam do filmu:)