Вся суть профессии в одной строчке кода

Вся суть профессии в одной строчке кода

SiteBot·

На хабре вышла статья (https://habr.com/ru/companies/timeweb/articles/769844/) под названием "8 углубленных вопросов на собеседованиях на роль сеньора в JavaScript". И вот что меня там сильно задело, решение данного кода:

console.log([] == ![]); // true

Ниже автор описывает почему в результате истина. Не поленюсь скопировать сюда это безумие:

Раскрыть

Давайте сначала рассмотрим типы обоих операндов:

typeof([]) // "object"
typeof(![]) // "boolean"

[] это объект, что ясно. Поскольку все в JavaScript является объектом, включая массивы и функции. Но почему операнд ![] имеет тип boolean? Давайте попробуем разобраться в этом. Когда вы используете! при использовании примитивного значения выполняются следующие преобразования:

* Ложные значения: Если исходное значение является ложным значением (например, false0nullundefinedNaN или пустая строка ''), применение ! преобразует его в значение true.
* Истинные значения: Если исходное значение является истинным значением (любое значение, которое не является ложным), применение ! преобразует его в значение false.

В нашем случае [] — это пустой массив, который является истинным значением в JavaScript. Поскольку [] является истиной, ![] становится ложью. Таким образом, наше выражение становится:

[] == ![]
[] == false

Теперь давайте продвинемся вперед и разберемся с оператором ==. Всякий раз, когда сравниваются 2 значения с использованием оператора ==, JavaScript выполняет Алгоритм Сравнения Абстрактного Равенства. Алгоритм состоит из следующих шагов:

image

Abstract Equality Comparison Algorithm

Как вы можете видеть, этот алгоритм учитывает типы сравниваемых значений и выполняет необходимые преобразования.

Для нашего случая давайте обозначим x как [], а y как ![]. Мы проверили типы x и y и обнаружили, что x является объектом, а y — boolean. Поскольку y является boolean, а x — объектом, применяется условие 7 из алгоритма сравнения абстрактного равенства:

Если Type(y) – Boolean, верни результат сравнения x == ToNumber(y).

Это означает, что если один из типов является логическим, нам нужно преобразовать его в число перед сравнением. Каково значение ToNumber(y)? Как мы видели, [] — это истинное значение, отрицание делает его false. В результате Number(false) равно 0.

[] == false
[] == Number(false)
[] == 0

Теперь у нас есть сравнение [] == 0, и на этот раз вступает в игру условие 8:

Если Type(x) является String или Number, а Type(y) — Object, верни результат сравнения x == ToPrimitive(y).

Исходя из этого условия, если один из операндов является объектом, мы должны преобразовать его в примитивное значение. Вот тут-то и появляется алгоритм ToPrimitive. Нам нужно преобразовать x, который равен [], в примитивное значение. Массивы — это объекты в JavaScript. Как мы видели ранее, при преобразовании объектов в примитивы в игру вступают методы valueOf и toString. В этом случае valueOf возвращает сам массив, который не является допустимым примитивным значением. В результате мы переходим к toString для получения выходных данных. Применение метода toString к пустому массиву приводит к получению пустой строки, которая является допустимым примитивом:

[] == 0
[].toString() == 0
"" == 0

Преобразование пустого массива в строку дает нам пустую строку "" и теперь мы сталкиваемся со сравнением: "" == 0.

Теперь, когда один из операндов имеет тип string, а другой — тип number, выполняется условие 5:

Если Type(x) — строка, а Type(y) — число, верни результат сравнения ToNumber(x) == y.

Следовательно, нам нужно преобразовать пустую строку "" в число, которое дает нам 0.

"" == 0
ToNumber("") == 0
0 == 0

Наконец, оба операнда имеют одинаковый тип, и выполняется условие 1. Поскольку оба имеют одинаковое значение, конечный результат равен:

0 == 0 // true

Для начала хочется передать отдельный привет всем тем, кто пишет, что "современный фронтенд - это легко", подразумевая изучение этого выкидыша IT-индустрии - языка JavaScript.

А дальше хочется пофилософствовать. Бог создал человека, даровал ему жизнь и целый необъятный мир в придачу. А ещё порядка 60-80 лет жизни. И что в итоге? В итоге некоторые из них пришли к тому, что выбрали для себя не реальную жизнь, не мир, дарованный Богом, а то, что приведено выше - копание в какой-то нелогичной чертовщине, где одна строчка кода требует объяснения на 3000 символов, а совокупное время на изучение всей этой "науки" - годы жизни, просиженные на заднице возле коробки монитора 30х40.

И чёрт бы с ним, с JavaScript-ом, так ведь почти вся сфера, почти всё IT построено на этом садомазохизме, где нужно прилагать какие-то нечеловеческие усилия в виде постоянного обучения и содержания в голове огромного массива узконаправленной информации. Технологии не становятся легче или логичнее - они лишь преумножаются в своём количестве, валятся как снежный ком с горы, становясь всё более сложными, а вместе с ними растут и требования в вакансиях.

Покажите эту статью вайтишникам, мечтающим писать код "не напрягаясь", пусть десять раз подумают, прежде чем без вазелина лезть в эту сферу.

Комментарии (259)

Правила комментирования
  • Любые темы про политику, войны, или всё то, что НЕ относится к теме сайта, будут УДАЛЯТЬСЯ.
  • Всё, что попадает под возможные нарушения законодательства РФ (экстремизм, призывы, дискредитация, оправдание, возбуждение и т.п.) - тоже.
  • Любые бессмысленные оскорбления участников сайта или тематики сайта. Если с чем-то не согласны - приводите аргументацию, а не оскорбления.
  • Запрещается упоминание в негативном контексте (клевета) каких-либо персоналий - физических или юридических лиц.

Мы стараемся сделать комментарии ценным информационным материалом, засорять сайт мусорными обсуждениями, никак не относящимися к теме сайта, не нужно! Спасибо за понимание.

0 / 10000

Форматы: JPG, PNG, WebP. Не более 5 файлов (по 10 МБ). Можно вставить из буфера (Ctrl+V).

Загрузка комментариев…