Den bedste JavaScript-meme, jeg nogensinde har set, forklaret i detaljer

TLDR: Tving dig selv til at bruge tredobbelt lig.

Jeg har utilsigtet fundet dette JavaScript-meme på Reddit, og det er det bedste, jeg nogensinde har set.

best-js-meme-to-date-2

Du kan kontrollere dette memmes nøjagtighed ved at køre hvert kodestykke i Developer Tools. Resultatet er ikke overraskende, men stadig lidt skuffende.

Selvfølgelig får dette lille eksperiment mig til at undre mig ...

Hvorfor sker dette?

hvorfor-sker-dette-sker

Med erfaring har jeg lært at omfavne JavaScript's glatte sider, mens jeg bevæger sine stikkende fyrretræer. Ikke desto mindre kaldte detaljerne i dette hjørnesag mig stadig.

Det er ligesom Kyle Simpson siger ...

"Jeg tror ikke, nogen nogensinde virkelig kender JS, ikke alligevel."

Når disse sager dukker op, er det bedst at konsultere kilden - den officielle ECMAScript-specifikation, som JavaScript er bygget fra.

Med spec i hånden, lad os dybt forstå, hvad der foregår her.

Panel 1 - Introduktion af tvang

panel-1-1

Hvis du kører 0 == "0"i din udviklerkonsol, hvorfor vender den tilbage true?

0er et tal og "0"er en streng, de skal aldrig være det samme! De fleste programmeringssprog respekterer det. 0 == "0"i Java returnerer for eksempel dette:

error: incomparable types: int and String 

Dette giver perfekt mening. Hvis du vil sammenligne en int og streng i Java, skal du først konvertere dem til samme type.

Men dette er JavaScript, I'all!

dette-er-javascript

Når du sammenligner to værdier via ==, kan en af ​​værdierne underkastes tvang .

Tvang - Ændring af en værdi automatisk fra en type til en anden.

Automatisk er nøgleordet her. I stedet for at du eksplicit konverterer dine typer, gør JavaScript det for dig bag kulisserne.

scumbag-javascript

Dette er praktisk, hvis du bevidst udnytter det, men potentielt skadeligt, hvis du ikke er opmærksom på dets implikationer.

Her er den officielle ECMAScript Language Specification om det. Jeg omskriver den relevante del:

Hvis x er tal og y er streng, returneres x == til nummer (y)

Så for vores sag om 0 == "0":

Da 0 er nummer og "0" er streng, returneres 0 == til nummer ("0")

Vores streng "0"er hemmeligt konverteret til 0, og nu har vi en kamp!

0 == "0" // true // The second 0 became a number! // so 0 equals 0 is true.... 

den streng blev hemmeligt et nummer

Underligt, ikke? Nå vænne sig til det, vi er ikke engang halvvejs færdige.

Panel 2 - Arrays bliver også tvunget

panel-2

Denne vrøvl er ikke begrænset til primitive som strenge, tal eller booleanske. Her er vores næste sammenligning:

0 == [] // true // What happened...? 

Tvang igen! Jeg omskriver specs relevante del:

Hvis x er streng eller tal, og y er objekt, skal du returnere x == ToPrimitive (y)

Tre ting her:

1. Ja, arrays er objekter

arrays-er-objekter

Undskyld at bryde det dig.

2. Tom matrix bliver tom streng

Igen ifølge specifikationen leder JS først efter et objekts toStringmetode til at tvinge det.

I tilfælde af arrays toStringslutter det sig til alle dets elementer og returnerer dem som en streng.

[1, 2, 3].toString() // "1,2,3" ['hello', 'world'].toString() // "hello,world" 

Da vores array er tomt, har vi intet at deltage i! Derfor...

[].toString() // "" 

tom matrix-tvang-til-tom-streng-1

Specifikationerne ToPrimitiveforvandler dette tomme array til en tom streng. Referencer er her og her for din bekvemmelighed (eller forvirring).

3. Tom streng bliver derefter 0

tomme strenge-bliver-0

Du kan ikke finde på disse ting. Nu hvor vi har tvunget arrayet til "", er vi tilbage til den første algoritme ...

Hvis x er tal og y er streng, returneres x == til nummer (y)

Så for 0 == ""

Da 0 er nummer og "" er streng, returneres 0 == til nummer ("")

ToNumber("") returnerer 0.

Derfor 0 == 0endnu en gang ...

tvang-hver-gang-2

Panel 3 - Hurtig opsummering

panel-3-1

Det er rigtigt

0 == "0" // true 

Fordi tvang gør dette til 0 == ToNumber("0").

Det er rigtigt

0 == [] // true 

Fordi tvang løber to gange:

  1. ToPrimitive([]) giver tom streng
  2. ToNumber("")Giver derefter 0.

Så fortæl mig ... i henhold til ovenstående regler, hvad skal dette returnere?

"0" == [] 

Panel 4 - FALSK!

panel-4-1

FALSK! Korrekt.

Denne del giver mening, hvis du har forstået reglerne.

Her er vores sammenligning:

"0" == [] // false 

Henviser til specifikationen igen:

Hvis x er streng eller tal, og y er objekt, skal du returnere x == ToPrimitive (y)

Det betyder...

Da "0" er streng og [] er objekt, returneres x == ToPrimitive ([])

ToPrimitive([])returnerer tom streng. Sammenligningen er nu blevet

"0" == "" 

"0"og ""er begge strenge, så JavaScript siger, at der ikke er behov for mere tvang . Det er derfor, vi får false.

Konklusion

bare-brug-tredobbelt-lig

Brug tredobbelt lig og sov godt om natten.

0 === "0" // false 0 === [] // false "0" === [] // false 

Det undgår tvang fuldstændigt, så jeg antager, at det også er mere effektivt!

Men præstationsforøgelsen er næsten meningsløs. Den virkelige gevinst er den øgede tillid, du har til din kode, hvilket gør det ekstra tastetryk helt umagen værd.

Vil du have gratis coaching?

Hvis du vil planlægge et gratis opkald på 15-30 minutter for at diskutere Front-End-udviklingsspørgsmål vedrørende kode, interviews, karriere eller andet, følg mig på Twitter og DM mig.

Derefter, hvis du nyder vores første møde, kan vi diskutere et løbende coachingforhold, der hjælper dig med at nå dine Front-End-udviklingsmål!

Tak for læsningen

For mere indhold som dette, se //yazeedb.com!

Indtil næste gang!