Привет, Хабр! Представляю вашему вниманию перевод статьи «To Wash It All Away» автора James Mickens.



Когда я учился в аспирантуре в Анн-Арбор, у меня был друг, глубоко увлеченный движением защитников окружающей среды. Он покупал еду у местных фермеров, ездил на велосипеде вместо машины, желая уменьшить выбросы, и держал жуткое компостное ведро, которое, вероятно, будет источником следующей пандемии гриппа. Однажды он сказал мне, что собирается неделю пожить на ферме. Я спросил зачем, и он ответил, что хочет «побыть ближе к земле» — фраза, которую вы можете произнести с серьёзным лицом, только комментируя документальный фильм о древних южноамериканских племенах. Я сказал моему другу, что земля не хочет побыть ближе к нему и что если бы он действительно присмотрелся к земле, то увидел бы не молочные реки и кисельные берега, а голод, стервятников, непосильный труд с использованием тачек и в целом неприемлемые количества насекомых. Он разразился продолжительной лекцией об экологической ответственности, которую я тут же выбросил из головы, потому что понял, что мой наивный друг даст дуба на этой ферме, и посоветовал ему без колебаний возвращаться, если вдруг ему там будет недостаточно хорошо. Он улыбнулся мне так, как улыбаются люди в фильмах ужасов за минуту до встречи с топором, и отчалил. Ровно 37 часов спустя он позвонил. Я поинтересовался, как идут дела, на что он ответил протяжным, леденящим душу звуком, подобным пению сирен в брачный период. Я попросил его описать свой первый день, и он ответил, что всё его бытие вращалось вокруг блеющих вещей: блеющих коз, хотевших есть, блеющих ворон, хотевших стырить еду у блеющих коз и блеющих механизмов, состоящих из вращающихся стальных лезвий и не имеющих никакого разумного применения, не считая обеспечения вам членства в клубе «Протез месяца».
Я спросил своего друга, когда же он собирается домой, на что он ответил, что звонит с вокзала в Анн-Арбор; он уже здесь. А затем он опять выдал тот вой сирен, тот жуткий, протяжный звук, и я понял — ПОХОЖЕ, ЭТО ПЕРВЫЙ СИМПТОМ КОМПОСТОВЕДЕРНОГО ГРИППА.

ИТ-специалисты часто видят в веб-страницах то, что мой друг видел в фермах. Люди думают, что веб-браузеры — это такие элегантные вычислительные платформы, и что веб-страницы — это такие легкие, пушистые штуковины, которые вы можете редактировать в блокноте, перекидываясь ироничными комментариями с друзьями в кофешопе. Нет ничего более далекого от истины. Современная веб-страница — это катастрофа. Она подобна сцене с одной из тех апокалиптических средневековых картин, изображающих последствия пришествия Галактуса: люди катятся кубарем в огненную бездну, сокрушаются различными сокрушающими штуками и свисают с оборудования для детских площадок, которое не прошло бы сертификацию безопасности. Это именно то, что вы увидите, взглянув на HTML, CSS и JavaScript в современной веб-странице. Нет, разумеется, ни один человек не в состоянии действительно «взглянуть» на это содержимое, потому что типичная веб-страница в наши дни подобна V'Ger из первого Стар Трека — технология, которую мы когда-то понимали, а теперь не можем даже осознать, сокрушающий левиафан кода и разметки, написанных людьми настолько ненадежными, что они тут даже не третья сторона, они пятая сторона, вообще НЕ ЗВАННАЯ на эту вечеринку, но явившаяся всё равно, потому что хиппи были правы и свободная любовь или пофиг. Я уверен, что веб-браузер — один из тех «нечестивых притонов», о которых постоянно твердят по Fox News; Я бы проверил это лично поиском в сети, но поиск в сети потребовал бы от меня использования браузера, А ЭТО ИМЕННО ТО, ЧТО ВЕЗДЕСУЩИЕ ЛИБЕРАЛЬНЫЕ ЭЛИТЫ ОТ МЕНЯ ХОТЯТ.

Описание того, почему Веб ужасен, подобно описанию того, почему ужасно тонуть в океане из рыб фугу, беременных маленькими Фредди Крюгерами — каждая деталь кошмарна сама по себе, но совокупная сумма восхитительно складывается в вечнозелёный цветок ненависти. Например, Консорциум Всемирной паутины (W3C) предоставляет «официальные» спецификации для многих веб-технологий на стороне клиента. К сожалению, эти спецификации являются обязательными к исполнению производителями браузеров примерно в той же степени, в которой вы, в принципе, можете попросить ядозуба встретить вас в аэропорту[1], но у ядозуба, пожалуй, найдутся более интересные занятия. Каждый документ W3C наполнен омерзительными предложениями, в основном состоящими из гиперссылок на гиперссылки. Например, если вы производитель браузера и хотите добавить поддержку HTML селекторов, вы должны помнить, что на третьем этапе разбора строки селектора «Если результат недействителен ([SELECT], раздел 12), следует бросить исключение SYNTAX_ERR ([DOM-LEVEL-3-CORE], раздел 1.4) и прервать этот алгоритм». Подобный романтический этюд в канцелярских тонах, несомненно, будет по нраву людям, тоскующим по тупости списка ингредиентов Доширака, помноженного на многослойную бюрократию Советского Союза. Действительно, можно представить себе мир, в котором производители браузеров нанимают легионы толкователей Талмуда, дабы понять, почему SYNTAX_ERR именно оранжевый, а не лиловый, и как именно эта оранжевость относится к оскобоченной лиловости ([DOM-LEVEL-3-CORE]). А еще можно представить себе мир, где производители браузеров таким не занимаются, реализуя вместо этого 53% каждой спецификации, а затем надеясь, что ни одна веб-страница не попытается использовать HTML селекторы, затем интерфейс геолокации, а затем тег <canvas>, потому что это комбо освободит Антихриста и/или отобразит веб-страницу, подобную одной из тех работ Пикассо, которые вы якобы понимаете, но которые все втихаря хотят выбросить в океан, потому что никому нет радости созерцать изображение голубого человека из равнобедренных треугольников с растущей изо лба гитарой без всякой на то причины.

[1] «Ядозубы встретят тебя в аэропорту» — название реальной детской книжки, оказавшей огромное влияние на мой эмоциональный рост. Её неустрашимый реализм вдохновил меня на написание моей собственной серии негативно воспринятых детских книг, таких как «Пауки съели твою сестру, о которой мы никода не говорим», «Капиталистическая реклама заставляет тебя ненавидеть своё тело и покупать вещи, созданные рабским трудом» и «Я могу солгать и сказать, что мне интересна твоя коллекция комиксов, или сказать правду и пояснить, почему с тобой не хотят встречаться».

Учитывая невыносимое разбухание веб-стандартов и клоунски невнятную семантику этих стандартов, производителям браузеров стоит просто плюнуть и посоветовать обществу перестать хотеть странного. Однако, это мнение непопулярно, потому что никто не станет смотреть ваше выступление на TED, если ваше чувство оптимизма базируется на реальности. Я то и дело пытаюсь объяснить друзьям, почему они должны отказаться от веб-страниц и обмениваться информацией с помощью солнечного света, отраженного от системы зеркал, ну или энергичного махания цветными флажками. Мои друзья неизбежно отвечают бессмысленным набором слов типа «люди изобрели летательные аппараты, поэтому мы, несомненно, в состоянии сделать хороший браузер!». К сожалению, критерий успешности летательного аппарата прост («Я ЭТО Я НО Я ПТИЦА»), в то время как критерий успешности веб-браузера включает в себя каскадные таблицы стилей — технологию, одним своим существованием обрекающую любой проект на былинную неудачу. Для непосвященных, каскадные таблицы стилей — это такая тайнопись, разработанная масонами для сокрытия визуальной природы реальности и побуждения людей к рисованию картин псевдографикой. CSS-файлы якобы позволяют вам отделить определение вашего содержимого от определения того, как это содержимое выглядит — используя CSS, вы можете задать размещение для ваших HTML тегов, а также шрифтов и цветовых схем, используемых этими тегами. К сожалению, CSS и HTML сочетаются так же, как инструкция по сборке вашей кровати из IKEA и набор злобных деревянных палок, якобы таящих в себе структуру кровати. CSS — это не столько описание того, как ваша веб-страница будет в конце концов выглядеть, сколько поверхностный, высокоуровневый обзор того, что может случиться с вашей страницей в зависимости от погоды, ситуации на фондовом рынке и когда вы последний раз звонили маме. Подобно наивному гейм-мастеру, не испорченному печалями взрослой жизни, вы создаёте абстрактные CSS классы для тегов <div> и тегов <span>, распределяя их сильные и слабые стороны, и определяя роли, которые они будут играть во всеобъемлющем и возвышенном повествовании вашего HTML. Всё строго на своих местах; вы загружаете страницу в браузер и готовитесь к славной победе. Однако, вскоре вы обнаруживаете, что ваш тег <эльф> имеет лишний вес. ЭЛЬФ НЕ МОЖЕТ ИМЕТЬ ЛИШНИЙ ВЕС. Даже хуже, у вашего тега <варвар> нет здоровенного молота или топора. Без здоровенного молота или топора ВАШ ВАРВАР ПРОСТО НЕГРАМОТНЫЙ КАЧОК. А потом вы смотрите на ваш тег <маг> и видите, что это не белый старикан с развевающейся бородой, а молодой негр из Бруклина. ПО МНОЖЕСТВУ КОМПЛЕКСНЫХ ПРИЧИН, БЕРУЩИХ СВОЁ НАЧАЛО В ЕВРОПЕЙСКИХ КОЛОНИАЛЬНЫХ ПОВЕСТВОВАНИЯХ, ВАШ МАГ ОБЯЗАН БЫТЬ БЕЛЫМ СТАРИКАНОМ С РАЗВЕВАЮЩЕЙСЯ БОРОДОЙ, А НЕ НЕГРОМ В ХИПСТЕРСКИХ ТУФЛЯХ И С РОСКОШНОЙ КОЛЛЕКЦИЕЙ ПЛАСТИНОК. Таковы беды, что посеет вам CSS. Или пожнёшь ты. Честно говоря, я не знаю, какой глагол и в какой форме тут более уместен, но, уверен, что вы меня поняли. На рисунке 1 конкретный пример CSS-ного посевательства. Или CSS-овского посевательства. МОИ НЕКАСКАДНЫЕ РУКОВОДСТВА ПО СТИЛЯМ СРАЖАЮТСЯ ЗА МОЮ ДУШУ.



Рисунок 1: Как-то раз я пытался соорудить кроссбраузерную отладочную инфраструктуру. У меня была клиентская JavaScript библиотека, способная пройтись по куче JavaScript'а и отобразить забавные штуки о состоянии страницы. Мои друзья-гуманитарии уверили меня, что вывод в консоль — удел неандертальцев, так что я сделал интерфейс на HTML для отображения диагностической информации. Первая версия интерфейса использовала политики компоновки браузера по умолчанию. Совсем как Икар, я мечтал о большем, поэтому я решил сделать Вычурную КомпоновкуTM. Я написал CSS с указаниями, должны ли мои теги быть расположены статически, динамически или же относительно знака зодиака. Вот что я узнал: никогда не указывайте, должны ли ваши теги быть расположены статически, динамически или же относительно знака зодиака. Как только один-единственный тег сбросит оковы автоматического процесса компоновки, браузер немедленно поедет крышей и сложит случайные HTML-теги кучкой вдоль оси Z, оси, видимо, являющейся приемлемым вариантом, даже если ваш монитор может отображать только два измерения. В конце концов я нашел рабочий файл CSS в бутылке, выброшенной на берег, и твикал его до тех пор, пока он не заработал в моем интерфейсе. Потом я пошел домой, роняя скупые мужские слёзы, наполненные сюрикенами и превращающиеся во львов, едва касаясь земли.

Если вы веб-разработчик, CSS — лишь одна из ваших забот. Совокупный стек веб-технологий настолько хрупок, что разработчики просто смирились с тем, что различные части веб-страницы будут отваливаться в произвольные моменты времени. Видимо, это норма, потому что электронную коммерцию никто не воспринимает всерьез, и, если вы действительно жаждете безопасных банковских операций, вы не прочь посетить банк лично, как в 19 веке, вместо использования веб-портала банка, постоянно (но втихаря) извергающего ошибки исполнения в консольный лог (консольный лог, который браузер по умолчанию вам не показывает, потому что если бы вы знали о нём и внемлили его горестным былинам, вы бы бросили информатику и переключились на изготовление деревянных башмаков).
На рисунке 2 представлен оригинальный пример такого консольного лога; лог был сгенерирован реальной веб-страницей на одном популярном сайте.


Рисунок 2: Они сказали, что я могу быть кем угодно, и теперь я лог ошибок веб-браузера. У меня пятнадцать кошек, где все вечеринки?

  • Первая запись лога говорит нам, что браузер исполнил загруженный файл как JavaScript, несмотря на то, что MIME тип файла — text/html. Мой вам совет: если вы не в курсе, что перед вами, НЕ ИСПОЛНЯЙТЕ ЭТО В НАДЕЖДЕ ПОЛУЧИТЬ БОЛЬШЕ ИНФОРМАЦИИ. Это все равно что подметить, что ваш сосед — жуткий оборванец с бегающими глазами, а затем начать ложиться спать у него на пороге, используя тряпку с хлороформом в качестве подушки, исключительно чтобы убедиться, что он не станет привязывать вас к батарее и заставлять раскрашивать крошечные фигурки. Я скажу вам, чем это кончится: ВЫ РАСКРАШИВАЕТЕ КРОШЕЧНЫЕ ФИГУРКИ.
  • Вторая и третья ошибки говорят нам, что в скрипте страницы используется имя переменной, считающееся устаревшим в строгом режиме, но приемлимое в вычурном режиме. Даже не знаю, с какого конца начинать этот прелестный рогалик, начинённый ужасом? Внемлите же: когда мужчина и женщина влюбляются, они хотят продемонстрировать друг другу свои чувства. А потому они заставляют браузеры поддерживать различные режимы исполнения. «Стандартный режим» ссылается на ненадежные интерфейсы браузера, описанные в последних спецификациях HTML и CSS. «Вычурный режим» ссылается на ненадежные интерфейсы браузера, существовавшие в браузерах во времена администрации Эйзенхауэра. Вычурный режим был создан из-за того, что множество веб-страниц также было создано во времена администрации Эйзенхауэра и компьютерная индустрия хотела сохранить сетевые разглагольствования о том, как «рок-н-ролл» развращает нашу молодежь. Вычурный режим выжил потому, что веб-разработчики узнали о вычурном режиме и использовали его в качестве предлога, чтобы не учиться новым трюкам. Но потом нашлись и веб-разработчики, хотевшие учиться новым трюкам, поэтому был придуман стандартный режим, позволяющий этим разработчикам ходить по старым граблям на новый лад. А ещё есть третий режим браузера под названием «почти стандартный режим»; этот режим аналогичен стандартному, за исключением того, что он выводит изображения внутри ячеек таблицы, используя алгоритм вычурного режима. По причинам, съеденным антилопой гну, «почти стандартный режим» также называют «строгим» режимом, хотя он и менее строг, чем стандартный режим. По причинам, чудовищным настолько, что антилопа гну отказалась их есть, не существует полностью надежного способа заставить все браузеры загрузить страницу в одном и том же режиме совместимости. Таким образом, даже если ваша страница прочтет все рекомендуемые заклинания, браузер по-прежнему может делать то, что он хочет и так, как он хочет. И именно отсюда берутся дети.
  • Четвертая и седьмая ошибки представляют собой необработанные исключения JavaScript. В адекватной вселенной одно-единственное необработанное исключение завершит программу, а если бы программа продолжила выполняться после возникновения такого исключения, мы бы поняли, что наступил Рагнарёк и Один не в духе. В мире браузеров же игнорирование необработанных исключений называются «среда, а также все дни, которые не 'среда'». Циклу событий JavaScript мало дела до традиционных понятий о надежности программного обеспечения, а потому, если обработчик события бросит исключение, цикл событий натурально сделает вид, что ничего не произошло, и пойдет дальше. Этот цирк с конями продолжается, даже если, как в случае с седьмой ошибкой, веб-страница пытается вызвать init() у объекта, не имеющего метода init(). Вы должны испытывать дискомфорт от осознания того, что у веб-страницы раздвоение мнения о наличии процедур инициализации, но странице по прежнему дозволено вытворять всякое. Такое резкое несоответствие ожиданий действительности было бы неприемлемо в любом другом контексте. Вы бы огорчились, если бы легли в больничку вырезать аппендицит и во время операции хирург сказала «Я НЕ ОЖИДАЛА, ЧТО У ВАШЕЙ ПЕЧЕНИ БУДУТ ЖАБРЫ», а затем продолжила действовать по своему изначальному хирургическому плану, несмотря на то, что вы, похоже, русалка. То, что вы русалка, должно иметь неигнорируемые последствия в материальной вселенной. Аналогично, если веб-страница думает, что объект должен быть инициализирован, но у объекта нет метода инициализации, браузер не должен ржать и продолжать, полагая, что остальной части страницы безразлично, состоят ли её объекты из белиберды.

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

На этом месте должно стать интуитивно понятно, что разные браузеры могут или не могут генерировать один и тот же лог ошибок для одной и той же страницы. В общем случае, если веб-страница содержит более трёх бит энтропии, разные браузеры будут генерировать экстравагантно уникальные сочетания намерений веб-разработчика и шизофреничной звериной палитры, используемой браузерами для передачи картины мира. Таким образом, выбор «лучшего браузера» подобен игре в одно из тех жутких упражнений на укрепление доверия, где вы решаете, какие три из ваших пяти чувств вы предпочли бы потерять, а потом ваши коллеги ругают вас за компромиссы, на которые им пришлось пойти, несмотря на то, что не существует частичного упорядочивания, способного сопоставить несчастные случаи при дайвинге, в ходе которых вы теряете ваши глаза и уши, с несчастными случаями на производстве, в ходе которых вы теряете свои нос и язык. Все варианты плохи; это мир топтания на месте. Действительно, попытки выбрать лучший браузер подобны попыткам решить, кто из ваших никчемных детей должен унаследовать семейный бизнес. Маленький Оливер отвергает общепринятые понятия о том, что должен делать цикл обработки событий, поэтому всякий раз, когда пользователь нажимает клавишу на клавиатуре, Оливер запускает не одно событие keyPress, а три события KeyDown, событие KeyUp и вырезанное соло саксофона из восьмой симфонии Моцарта. Дражайшая Фиона, непреклонный трудоголик, проектирует свой браузер так, что когда вы «закрываете» его, графический интерфейс исчезает, но основной процесс крутится в фоновом режиме, тихо, злобно и медленно потребляя записи в таблицах ядра и делая невозможным перезапуск браузера без созерцания сообщения об ошибке «Где-то на белом свете работает другая копия браузера; найди Кармен СанДиего и она раскроет секрет». Любимый Кристофер, в попытке сделать свой браузер быстрым и легким, решает заменить его Flash-плагин кодом, который печатает «Shockwave упал», а затем сразу разыменовывает нулевой указатель; это гарантирует, что большинство ваших попыток посмотреть видео закончатся желанием более приземлённых зрелищ типа резьбы по дереву или наскальной живописи. И бедный IE6, он же «из этого точно толка не будет, потому что IE6 не является правильным христианским именем», ухитряющийся как-то ковылять по миру, переживая больше покушений, чем Фидель Кастро.

Каждый браузер безрассуден и причудлив по-своему, но все браузеры одинаково разделяют любовь к эпичной подкачке на диск. Не редкий дождик из миниатюрных I/O, выровненных по границам размещения файловой системы, нет, я говорю о столкновениях снежных штормов чтения и записи, о первобытном потопе, заставляющем вас собирать своих соплеменников и решать, каких тварей брать по паре и не забыть ли огненных муравьев, ведь огненные муравьи портят лето. Браузерам не нужна конкретная причина для ушатывания диска, нет; подкачка — образ жизни браузеров, досуг, доставляющий сам по себе. Если вы не IT-специалист, вы просто смиряетесь с тем фактом, что посещение CNN.com заставит зеленую мигающую лампочку со значком цилиндра перестать мигать и светить зеленым постоянно. Однако, если вы таки знаете, как работают компьютеры, то бесконечная подкачка сводит вас с ума. Она превращает вас в Торквемаду — жалкую фигуру, одержимую страхом того, что вся ваша идеология — всего лишь вычурная ложь, нужная только лишь для того, чтобы скрыть чрезмерные дисковые операции серых кардиналов. Вы открываете ваш диспетчер задач, и обнаруживаете, что ваш браузер запустил 67 различных процессов, и все они называются «browser.exe», и все они отчаяннно палят изо всех I/O по таким загадочным областям файловой системы, как "\Roaming\горшки\сковородки\кэш\4$$Dtub.partial", где "\4$$" — экзотическая ESC-последовательность, раскрывающаяся в латвийский двойной умляут. Вы ищете в Интернете потенциальные решения и сталкиваетесь с кучей противоречивых и ничем не подкрепленных мнений: у вашего браузера вирус; у вашего вируса вирус; надо было использовать Emacs; надо было использовать vi, и именно поэтому ваш брак дал трещину.

Естественно, самый популярный совет для решения любых браузерных проблем — очистить кэш вашего браузера. Несомненно, очистка кэша иногда поможет, примерно так же, как пинание дерева нищебродом иногда приведёт к серии забавных событий, завершающихся падением на землю большого мешка с деньгами и запиской «Потрать всё! Цём, Жизнь.» К сожалению, пинание дерева, как правило, не приводит к богатству, так что ваш подкрепленный верой акт агрессии к деревьям на самом деле всего лишь делает вас диким, пинающим деревья монстром, порицаемом детьми и эмоционально чувствительными взрослыми. Аналогично, ваша внезапная очистка кэша браузера, несмотря на благие намерения, всего лишь местное болеутоляющее, ненадолго скрашивающее муки бытия. Исправление браузера очисткой кэша подобно вашему папе, подвозящему вас в детский сад, и, когда машина вдруг начинает дымиться, пытающемуся починить её тремя хлопками по капоту, а затем спрашивающему вас, чуете ли вы ещё монооксид углерода, и вы такой: «ага, уже лучше», потому что вам не хочется выставлять вашего папу жуликом, а затем вы оба проводите остаток пути молча, изо всех сил стараясь не потерять сознание.

Так что, да, было бы здорово, если бы исправление вашего браузера было связано с действиями, которые не были бы семантически эквивалентны вуду. Однако, с другой стороны, всё могло быть ещё хуже. Например, было бы действительно ужасно, если бы скриптовый язык вашего браузера сочетал в себе прототипное наследование Self, квазифункциональщину, позаимствованную из LISP, структурированный синтаксис, притянутый из C, и агрессивно-асинхронную модель ввода-вывода, требующую нетривиальных цепочек обратного вызова, охватывающих несколько поколений трудолюбивых американцев. О НЕТ, Я ТОЛЬКО ЧТО ОПИСАЛ JAVASCRIPT. Какой пренеприятный поворот событий! Люди жаждали комбинации Self, LISP и C столь же отчаянно, сколь жители Средиземья умоляли Сарумана скрестить орков с людьми, дабы получился Урук-хай. Орки и люди прекраснейше боролись за существование в своих отдельных общинах, создание новой расы с недостатками обоих — не самый лучший способ стать первым парнем на селе. Однако, несмотря на свои недостатки, JavaScript таки получил широкое распространение. Исследование причин сего подобно попыткам понять причины Первой мировой войны — все согласны с пятью основными причинами, но у всех своё мнение об их первостепенности. Суть такова: в 90-е годы, когда JavaScript и Java конкурировали за превосходство на клиенте, Java-апплеты были чудовищно медленны и не могли похвастаться взаимодействием с HTML; JavaScript же был только наполовину чудовищно медленен и мог паршиво (но мог) взаимодействовать с HTML. Так что Java проиграла, несмотря на:

  • JavaScript динамически типизирован, и его агрессивные правила приведения типов, похоже, были разработаны Monty Python. Например, 12 == «12», потому что строка приводится к числу. Это слегка тупо, но хотя бы имеет отдалённый смысл. А теперь рассмотрим тот факт, что null == undefined. Это полный бред; ссылка, указывающая на null, не может быть неопределенной, ОНА ПО ОПРЕДЕЛЕНИЮ УКАЗЫВАЕТ НА NULL. А теперь, когда вы размялись, посмотрите сюда: "\r\n\t" == false. Вот почему: браузер обнаруживает, что оба операнда имеют разные типы, поэтому он преобразует false к 0 и повторяет сравнение. Операнды всё еще имеют разные типы (строка и число), так что браузер приводит "\r\n\t" к числу 0, потому что с какого-то бодуна ненулевое количество символов равно 0. Вуаля — 0 равен 0! ШИКАРНО. Это объяснение подобно сюжету «Inception», за исключением того, что внедренной идеей было «корректность вашей программы приведена к false».
  • Здравствуй, добрый человек — дай мне согреть тебя этой холодной зимней ночью! Знаешь ли ты, что JavaScript определяет особое значение NaN («не число»)? Это значение является тем, что вы получаете, когда делаете такие глупости, как ParseInt(«БэтменНеЧисло»). Иными словами, NaN является значением, которое не является числом. Однако, typeof(NaN) возвращает… «число». Более логичным возвращаемым значением было бы «СЛАВА ВЕЛЬЗЕВУЛУ, ПОВЕЛИТЕЛЮ ТЬМЫ", но я отвлекся.
  • Кстати, NaN != NaN, так что Аристотель ошибался со всем этим «законом тождества».
  • Кроме того, JavaScript определяет два оператора тождественности (=== и !==), не выполняющих приведения типов, выполняемого стандартными операторами равенства; однако, NaN !== NaN. Короче, не используйте числа в JavaScript, а если уж у вас нет иного выхода, реализуйте программный ALU. Это медленно, но надёжно.
  • Хотя, на самом деле, недостаточно надёжно. В отличие от C++, использующего статическое описание интерфейсов класса, JavaScript использует прототипное наследование. Прототип представляет собой динамический объект, действующий как шаблон для «экземпляров» этого объекта. Например, если бы я захотел объявить класс Circle в JavaScript, я мог бы сделать что-то вроде этого:

    //Это конструктор, определяющий свойство "radius"
    //для новых экземпляров.
    function Circle(radius){
        this.radius = radius;
    }
    
    //Функция-конструктор содержит свойство объекта
    //под названием "prototype", определяющее дополнительные
    //атрибуты экземпляров класса.
    Circle.prototype.getDiameter = function(){
        return 2*this.radius;
    };
    var circle = new Circle(2);
    alert(circle.getDiameter()); //Выводит "4".

    Шаблоном объекта для класса Circle является Circle.prototype, и этот объект-прототип является обычным объектом JavaScript. Итого, путем динамического изменения свойств этого объекта, я могу динамически изменять свойства всех экземпляров этого класса. АГА, Я В КУРСЕ. Например, в какой-то случайный момент исполнениия моей программы, я могу сделать так…

    Circle.prototype.getDiameter = function(){
        return -5;
    };

    … и все мои круги будут думать, что их диаметр меньше, чем ничего. Это днище, но ещё хуже то, что прототипы предопределенных (или «родных») объектов JavaScript тоже могут быть переопределены. Так что если я сделаю что-то типа…

    Number.prototype.valueOf = function(){return 42;};

    … то любой числовой литерал, упакованный в объект Number, будет думать, что он ответ на главный вопрос жизни, вселенной, и всего такого:

    
    alert((0).valueOf());   //0 должен быть 0 для всех значений 0, но он 42.
    alert((1).valueOf());   //Зевс помоги, 1 тоже 42.
    alert((NaN).valueOf()); //NaN тоже 42. ОБЕЗГЛАВЬТЕ И СОЖГИТЕ МОЕ КОРЧАЩЕЕСЯ ТЕЛО

    Очевидно, что я получил то, что заслужил, если моя библиотека JavaScript переопределяет собственные прототипы, ломая мой собственный код. Однако, один-единственный фрейм веб-страницы содержит несколько библиотек JavaScript из нескольких источников, и кто его знает, какие ужасающие манипуляции с прототипами эти языческие библиотеки вытворяли перед запуском моей библиотеки. Это лишь одна из причин, почему от фразы «безопасность JavaScript» воспламеняются Библии.
  • Подобно C, JavaScript использует точку с запятой для завершения многих видов выражений. Однако, в JavaScript, если вы забыли точку с запятой, синтаксический анализатор JavaScript может автоматически вставить точку с запятой туда, где, по его мнению, эти точки с запятыми могли бы, возможно, обязаны, наверное, быть. Это кажется весьма полезным, пока вы не поймёте, что у точки с запятой есть семантический смысл. Вы не можете просто разбрасывать их вокруг, как будто вы Джонни Яблочное Зернышко от пунктуации. Автоматическая вставка точек с запятой в исходный код подобна игре в испорченный телефон, при условии, что каждое потерянное слово заменяется фразой «мать вашу». Это отличный способ освежить ваши межличностные отношения, но это не лучший способ парсить код. Некоторые библиотеки JavaScript намеренно начинаются с точки с запятой, чтобы гарантировать, что если вдруг эта библиотека будет дописана к другой (например, чтобы сократить количество HTTP запросов при загрузке), то синтаксический анализатор JavaScript не станет пытаться слепить последнее выражение первой библиотеки и первое выражение второй библиотеки в какую-то оргию выражений с точкой с запятой в качестве тамады. Такая начальная точка с запятой называется «защитная точка с запятой». Это самый печальный паттерн программирования, о котором я когда-либо слышал, и это при том, что я неплохо владею C++.

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

Итоги подведём — веб-браузеры подобны квантовой физике: в лучшем случае они предлагают вероятностные гарантии, а любой, кто утверждает, что полностью их понимает — лжец. На данном этапе развития человека есть более насущные проблемы: изменение климата, болезни сердца, плохое финансовое положение нигерийских принцев, желающих связаться с вами лично. Поскольку все эти проблемы не решены, просмотр веб-страниц — ужасный способ провести время; запуск нестабильных операционных систем, написанных для фана и загружающих странные файлы JavaScript от незнакомцев — последнее, чем нам стоит заниматься. Вместо этого нам стоит обмениваться информацией, используя ASCII сообщения фиксированной длины, написанные в статически проверяемом подмножестве латиницы, с изображениями, представленными в виде математических комбинаций отрезков линий, дуг и других вечных форм, описанных мертвыми философами, которые считали, что минотавры существуют, но не в силах выбраться из лабиринтов. Именно такое ясное мышление поможет нам победить космических египтян, выходящих из Звездных Врат. Ну или как там. Я американец и не силен в истории, но я твердо верю, что греки говорили на латыни, чтобы победить межгалактических египтян. #ДаешьПолемику! Короче, я хочу сказать, что браузеры слишком сложны, чтобы им доверять. К сожалению, дети тратят молодость впустую, и нынешнее поколение разработчиков программного обеспечения убеждено, что браузерам нужно больше фич, а не меньше. Так что нам предлагается возрадоваться тому, что браузеры превращают наши компьютеры в маленькие таверны из «Звездных войн», где рады каждому, и где вы можете выпить синего пойла, если вам хочется выпить синего пойла, и если что-то пойдет не так, то, возможно, джедай спасет вас, а если нет, ЭТО ЖЕ ТАВЕРНА ИЗ ЗВЕЗДНЫХ ВОЙН, ДААААА. Космические таверны хороши, но это фантастика; это просто куча сшитых вместе нелепых деталей для увеселения публики. Откройте глаза и узрите, что в реальном, негиперболичном мире, в котором вы живете, ваш браузер будет то и дело прерывать видео, а затем показывать мигание эпилептичных пикселей, издавая тот же звук, что издают телевизоры в японских фильмах ужасов перед тем, как бледное дитё сойдет с экрана и лишит вас гарантии. Это может произойти на самом деле, и мы должны всё это смыть.