Najbolji JavaScript meme koji sam ikad vidio, detaljno objašnjen

TLDR: Prisilite se da koristite trostruko jednako.

Nenamjerno sam pronašao ovaj JavaScript meme na Redditu, i to je najbolji koji sam ikad vidio.

best-js-meme-to-date-2

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?

zašto se to 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

ploča-1-1

Ako se pokrećete 0 == "0"u svojoj razvojnoj konzoli, zašto se vraća true?

0je 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!

ovo je javascript

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.

gad-javascript

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.... 

taj-niz-tajno-postao-broj

Čudno zar ne? Pa navikni se, nismo ni na pola gotovi.

Panel 2 - Nizovi se također prisiljavaju

ploča-2

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

nizovi-jesu-objekti

Žao mi je što te slomim.

2. Prazan niz postaje prazan niz

Ponovno, prema specifikaciji, JS prvo traži toStringmetodu objekta koja će je prisiliti.

U slučaju nizova, toStringspaja 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() // "" 

prazan-niz-prisiljava-na-prazan-niz-1

Specifikacija ToPrimitivepretvara ovaj prazan niz u prazan niz. Reference su ovdje i ovdje radi vaše udobnosti (ili zabune).

3. Prazan niz tada postaje 0

prazne-žice-postaju-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 == 0još jednom ...

prisila-svaki-put-2

Panel 3 - Brzo sažimanje

ploča-3-1

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:

  1. ToPrimitive([]) daje prazan niz
  2. Tada ToNumber("")daje 0.

Pa mi onda recite ... prema gornjim pravilima, što bi se ovo trebalo vratiti?

"0" == [] 

Panel 4 - NETOČNO!

ploča-4-1

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

samo-upotrijebi-trostruko-jednako

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!