Předvedeme si trochu trochu matoucí kod, ve kterém porovnává dva různé typy dat: číslo a pole.
Tipnete správně jestli se podmínka vyhodnotí na true
nebo false
?
if (32 == [32]) {
// true?
} else {
// false?
}
Pokud si nejste jistí, vysvětlíme si krok za krokem, jak JS dojde k odpovědi.
Primitivní datový typ a pole
Pro správné porovnání musíme nejprve dojít ke stejnému datovému typu, protože počítač neumí porovnat jabka a hrušky.
Při použití dvojitého rovná se == se provádí typové konverze, která vyhodnotí jako největší problém, že porovnáváme pole a primitivní hodnotu.
Pole tedy pomocí abstraktní operace toPromitive
, převede daný objekt na jeho primitivní hodnotu, která může být použita k porovnání s druhým operandem.
Dochází k automatické konverzi pole na řetězec, protože je volána metoda toString()
v rámci metody ToPrimitive()
.
Tento řetězec je pak porovnán s číslem pomocí operátoru ==
a dostáváme:
if (32 == "32") {
// true?
} else {
// false?
}
Porovnání primitivních datových typů
V tomto konkrétním případě už je vidět, že pravděpodobným výsledkem bude true
, protože řetězec "42" se při porovnání s číslem 42 vyhodnotí jako číslo 42.
Pokud máme na obou stranách stejný datový typ, tak se operátor dvojité a trojité rovná se chová identicky.
if (32 === 32) {
// true?
} else {
// false?
}
Nakonec si můžeme představit, že ještě dochází k finální konverzi na boolean, kterou se řídí podmínka if
.
Závěrem
Tento příklad ukázkou, proč koerze může být špatná věc. Tento JS kód může být trochu matoucí a provádí na pozadí mnoho věcí. Problém kódu je, že v první řadě děláte nesmyslné porovnání.
Změna na trojité rovná se, by problém nevyřešilo a změnila by funkčnost kódu. Pokud děláte smysluplné porovnání, například srovnáváte řetězec s číslem, může dávat použití dvojitého rovná se naprostý smysl.