Най-добрият JavaScript мем, който някога съм виждал, обяснен в детайли

TLDR: Принудете се да използвате тройни равни.

Неволно намерих този мем на JavaScript в Reddit и това е най-добрият, който някога съм виждал.

best-js-meme-to-date-2

Можете да проверите точността на този мем, като изпълните всеки кодов фрагмент в Developer Tools. Резултатът не е изненадващ, но все пак разочароващ.

Разбира се, този малък експеримент ме накара да се чудя ...

Защо се случва това?

защо се случва това

С опит се научих да прегръщам гладките страни на JavaScript, като същевременно обричам бодливите му борове. Независимо от това, детайлите на този ъгъл все още ме накараха.

Точно както казва Кайл Симпсън ...

"Не мисля, че някой наистина познава JS, не така или иначе напълно."

Когато тези случаи се появят, най-добре е да се консултирате с източника - официалната спецификация на ECMAScript, от която е изграден JavaScript.

С спецификацията в ръка, нека дълбоко разберем какво се случва тук.

Панел 1 - Въвеждане на принуда

панел-1-1

Ако използвате 0 == "0"вашата конзола за програмисти, защо се връща true?

0е число и "0"е низ, те никога не трябва да са еднакви! Повечето езици за програмиране уважават това. 0 == "0"в Java например връща това:

error: incomparable types: int and String 

Това е напълно логично. Ако искате да сравните int и String в Java, първо трябва да ги конвертирате в същия тип.

Но това е JavaScript, всички!

this-is-javascript

Когато сравнявате две стойности чрез ==, една от стойностите може да бъде подложена на принуда .

Принуда - Автоматична промяна на стойност от един тип на друг.

Автоматично тук е ключовата дума. Вместо даконвертирате изрично вашите типове, JavaScript го прави вместо вас зад кулисите.

мръсник-javascript

Това е удобно, ако целенасочено го експлоатирате, но потенциално вредно, ако не сте наясно с неговите последици.

Ето официалната спецификация на езика ECMAScript за това. Ще перифразирам съответната част:

Ако x е число и y е низ, върнете x == ToNumber (y)

Така че за нашия случай на 0 == "0":

Тъй като 0 е число и "0" е низ, върнете 0 == ToNumber ("0")

Нашият низ "0"е преобразуван тайно 0и сега имаме съвпадение!

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

този-низ-тайно-стана-номер

Странно, нали? Ами свикнете, дори не сме свършили наполовина.

Панел 2 - Масивите също се принуждават

панел-2

Тази глупост не се ограничава до примитиви като низове, числа или булеви числа. Ето нашето следващо сравнение:

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

Отново принуда! Ще перифразирам съответната част на спецификацията:

Ако x е низ или число и y е обект, върнете x == ToPrimitive (y)

Три неща тук:

1. Да, масивите са обекти

масиви-са-обекти

Съжалявам, че го разбивам.

2. Празният масив става празен низ

Отново според спецификацията, JS първо търси toStringметод на обект, за да го принуди.

В случай на масиви, toStringобединява всички негови елементи и ги връща като низ.

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

Тъй като масивът ни е празен, няма какво да се присъединим! Следователно...

[].toString() // "" 

empty-array-coerces-to-empty-string-1

Спецификацията ToPrimitiveпревръща този празен масив в празен низ. Справките са тук и тук за ваше улеснение (или объркване).

3. След това празният низ става 0

празните низове-стават-0

Не можете да измислите тези неща. След като принудихме масива да ""се върнем към първия алгоритъм ...

Ако x е число и y е низ, върнете x == ToNumber (y)

Така че за 0 == ""

Тъй като 0 е число и "" е низ, върнете 0 == ToNumber ("")

ToNumber("") връща 0.

Затова 0 == 0още веднъж ...

принуда-всеки път-2

Панел 3 - Бързо обобщение

панел-3-1

Това е вярно

0 == "0" // true 

Защото принудата превръща това в 0 == ToNumber("0").

Това е вярно

0 == [] // true 

Защото принудата тече два пъти:

  1. ToPrimitive([]) дава празен низ
  2. След това ToNumber("")дава 0.

И така, кажете ми ... според горните правила, какво трябва да върне това?

"0" == [] 

Панел 4 - FALSE!

панел-4-1

НЕВЯРНО! Правилно.

Тази част има смисъл, ако сте разбрали правилата.

Ето нашето сравнение:

"0" == [] // false 

Препращане към спецификацията още веднъж:

Ако x е низ или число и y е обект, върнете x == ToPrimitive (y)

Това означава...

Тъй като "0" е низ и [] е обект, върнете x == ToPrimitive ([])

ToPrimitive([])връща празен низ. Сега сравнението стана

"0" == "" 

"0"и ""двете са низове, така че JavaScript казва, че не е необходима повече принуда . Ето защо получаваме false.

Заключение

просто използване-тройно-равно

Използвайте тройни равни и спи спокойно през нощта.

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

Избягва изцяло принудата, така че предполагам и тя е по-ефективна!

Но увеличаването на производителността е почти безсмислено. Истинската печалба е повишената увереност, която ще имате във вашия код, което прави това допълнително натискане на клавиша напълно си заслужава.

Искате безплатен коучинг?

Ако искате да насрочите безплатно 15-30 минутно обаждане, за да обсъдите въпроси за разработка на Front-End относно код, интервюта, кариера или нещо друго, следвайте ме в Twitter и DM.

След това, ако се радвате на първата ни среща, можем да обсъдим продължаващи отношения на коучинг, които ще ви помогнат да постигнете целите си за развитие от предния край!

Благодаря за четенето

За повече съдържание като това разгледайте //yazeedb.com!

До следващия път!