TLDR: Prisilite se da koristite trostruko jednako.
Nenamjerno sam pronašao ovaj JavaScript meme na Redditu, i to je najbolji koji sam ikad vidio.
Točnost ovog mema možete provjeriti pokretanjem svakog isječka koda u Alatima za programere. Rezultat nije iznenađujući, ali ipak razočaravajući.
Naravno da me ovaj mali eksperiment natjerao da se zapitam ...
Zašto se ovo događa?
Iskustvom sam naučio prihvaćati glatke strane JavaScripta, dok sam ometao njegove bodljive borove. Bez obzira na to, detalji ovog kutnog slučaja i dalje su me zajebavali.
Baš kao što kaže Kyle Simpson ...
"Mislim da nitko nikada stvarno ne zna JS-a, u svakom slučaju ne potpuno."
Kada se ti slučajevi pojave, najbolje je potražiti izvor - službenu specifikaciju ECMAScript od koje je JavaScript izgrađen.
S specifikacijom u ruci, duboko shvatimo što se ovdje događa.
Panel 1 - Uvođenje prisile
Ako se pokrećete 0 == "0"
u svojoj razvojnoj konzoli, zašto se vraća true
?
0
je broj i "0"
niz, oni nikada ne bi trebali biti isti! Većina programskih jezika to poštuje. 0 == "0"
u Javi, na primjer, vraća ovo:
error: incomparable types: int and String
Ovo ima sasvim smisla. Ako želite usporediti int i String u Javi, prvo ih morate pretvoriti u isti tip.
Ali ovo je JavaScript, svi!
Kada usporedite dvije vrijednosti putem ==
, jedna od vrijednosti može se podvrgnuti prisili .
Prisila - Automatska promjena vrijednosti iz jedne vrste u drugu.
Automatski je ovdje ključna riječ. Umjesto da eksplicitno pretvorite svoje vrste, JavaScript to čini umjesto vas iza kulisa.
To je prikladno ako ga namjerno iskorištavate, ali potencijalno štetno ako niste svjesni njegovih posljedica.
Evo službene specifikacije jezika ECMAScript o tome. Parafraziram relevantni dio:
Ako je x broj, a y niz, vratite x == ToNumber (y)
Dakle, za naš slučaj 0 == "0"
:
Budući da je 0 broj, a "0" niz, vratite 0 == ToNumber ("0")
Naš je niz "0"
tajno pretvoren u 0
, i sada imamo podudarnost!
0 == "0" // true // The second 0 became a number! // so 0 equals 0 is true....
Čudno zar ne? Pa navikni se, nismo ni na pola gotovi.
Panel 2 - Nizovi se također prisiljavaju
Ova glupost nije ograničena na primitive poput nizova, brojeva ili logičkih vrijednosti. Evo naše sljedeće usporedbe:
0 == [] // true // What happened...?
Opet prisila! Parafraziraću relevantni dio specifikacije:
Ako je x niz ili broj, a y objekt, vratite x == ToPrimitive (y)
Tri stvari ovdje:
1. Da, nizovi su objekti
Žao mi je što te slomim.
2. Prazan niz postaje prazan niz
Ponovno, prema specifikaciji, JS prvo traži toString
metodu objekta koja će je prisiliti.
U slučaju nizova, toString
spaja sve njegove elemente i vraća ih kao niz.
[1, 2, 3].toString() // "1,2,3" ['hello', 'world'].toString() // "hello,world"
Budući da je naš niz prazan, nemamo se što pridružiti! Stoga...
[].toString() // ""
Specifikacija ToPrimitive
pretvara ovaj prazan niz u prazan niz. Reference su ovdje i ovdje radi vaše udobnosti (ili zabune).
3. Prazan niz tada postaje 0
Ne možeš izmisliti ove stvari. Sad kad smo primorali niz ""
, vratili smo se prvom algoritmu ...
Ako je x broj, a y niz, vratite x == ToNumber (y)
Tako za 0 == ""
Budući da je 0 broj, a "" niz, vratite 0 == ToNumber ("")
ToNumber("")
vraća 0.
Stoga, 0 == 0
još jednom ...
Panel 3 - Brzo sažimanje
To je istina
0 == "0" // true
Jer prisila pretvara ovo u 0 == ToNumber("0")
.
To je istina
0 == [] // true
Budući da prisila djeluje dva puta:
ToPrimitive([])
daje prazan niz- Tada
ToNumber("")
daje 0.
Pa mi onda recite ... prema gornjim pravilima, što bi se ovo trebalo vratiti?
"0" == []
Panel 4 - NETOČNO!
LAŽNO! Ispravno.
Ovaj dio ima smisla ako ste razumjeli pravila.
Evo naše usporedbe:
"0" == [] // false
Još jednom upućivanje na specifikaciju:
Ako je x niz ili broj, a y objekt, vratite x == ToPrimitive (y)
To znaci...
Budući da je "0" niz, a [] objekt, vratite x == ToPrimitive ([])
ToPrimitive([])
vraća prazan niz. Usporedba je sada postala
"0" == ""
"0"
i ""
oba su niza, tako da JavaScript kaže da više nije potrebno prisiljavanje . Zbog toga i dobivamo false
.
Zaključak
Koristite trostruka jednaka i mirno spavajte noću.
0 === "0" // false 0 === [] // false "0" === [] // false
U potpunosti izbjegava prisilu, pa pretpostavljam da je i ona učinkovitija!
Ali povećanje performansi gotovo je besmisleno. Prava je pobjeda povećano povjerenje u svoj kôd, čineći to dodatno pritiskanje tipki potpuno vrijednim.
Želite besplatni trening?
Ako želite zakazati besplatan 15-30-minutni poziv za raspravu o Front-end razvojnim pitanjima u vezi s kodom, intervjuima, karijerom ili nečim drugim, pratite me na Twitteru i DM-u.
Nakon toga, ako uživate u našem prvom sastanku, možemo razgovarati o kontinuiranom trenerskom odnosu koji će vam pomoći da postignete svoje razvojne ciljeve!
Hvala na čitanju
Za više ovakvih sadržaja pogledajte //yazeedb.com!
Do sljedećeg puta!