Я люто бешено ненавижу Javascript и никогда не устану об этом говорить.
- Вместо уродца, который имитирует синтаксис C, но при этом не имеет с ним ничего общего, в браузерах должен был быть нормальный православный Scheme, уже на тот момент существующий и известный.
- Javascript получил синтаксис C, который обманывает любого, кто начинает учиться программированию, просто как маркетинговый ход, чтобы быть похожим на Java. Вы же знаете, что абсолютно любой человек, не знающий разницу заранее, путает Java и Javascript? Так вот, это было сделано намеренно.
- Оператор `+` перегружен для строк и чисел, и делает разные вещи для этих типов. Более того, приведение типов выводит строки или числа из любых других объектов по правилам, которые так же легко выучить, как корейские частушки.
- Любая функция это замыкание, но одновременно с этим границами области видимости являются только тела функций, а не произвольные блоки кода. Слава Богу, в ES6 добавили let и const, с которыми можно избежать этого кошмара. Даже не заставляйте меня вспоминать семантику var и его отсутствия.
- Динамическая типизация без опциональных аннотаций типов. Учитывая, что современное приложение на Javascript может легко занимать несколько тысяч файлов по несколько сотен строк в каждом, успехов вам отслеживать поток данных, начиная от самой точки входа. Без Typescript или какого-нибудь Flow даже IDE вам не поможет понять, какие именно данные ожидает та или иная функция.
- В 2021 году никто не пишет непосредственно тот Javascript, который будет выполняться на браузере. У нас всегда есть хотя бы минификатор, который собирает финальный бандл для браузера. Это значит, что для того, чтобы запустить отладчик в браузере, нам нужны танцы с бубном, чтобы подключить source maps, или мы просто не можем ничего отлаживать. Вы думаете, что console.log это единственный и самый правильный способ отладки приложений? Да вы просто никогда не пробовали нормальные инструменты разработки.
- Фатальная ошибка в традиционном скомпилированном десктопном приложении? "Segmentation fault at...", которую мы хотя бы теоретически можем отдебажить, и которую нам может показать пользователь. Фатальная ошибка на фронтэнде? Белая страница, которая не говорит конечному пользователю вообще ничего.
- Понадобилось почти двадцать лет, чтобы в яваскрипте появилась модульность, и то только в node.js. Понадобилось ещё почти пять, чтобы модули начали худо-бедно поддерживаться нативно в браузере. Вдумайтесь в это: люди пишут на продакшене в языке, где нет вообще никакой модульности, до недавнего времени её нужно было имитировать!
- "Объектная" модель, не предполагающая никакой инкапсуляции. Мы в node.js можем переписать на ходу, в уже запущенном приложении, даже `process`. В браузере никто не сможет нам запретить переименовать или переопределить что угодно внутри `document` или `window`.
- Так как яваскрипт вырос из концепции скриптинга браузеров, абсолютно весь внешний тулчейн пришлось писать с нуля. В результате полностью пустой проект на Javascript в 2021 году содержит минимум три файла конфигурации: `package.json` , `.eslintrc.js`, и конфиг для вашего бандлера, что там у вас, Webpack, Parcel, Typescript. И все настройки в них должны быть аккуратно сбалансированы и синхронизированы. И дальше только хуже, с каждой дополнительной утилитой число конфигов только увеличивается.
- null это объект отдельного типа данных (null). Неинициализированные переменные получают значение не null, а undefined, объекты полностью другого типа данных, которые !== null. Если мы выполним недопустимую операцию на числах, мы получим NaN, объект типа Number, который не равен ни null, ни undefined. Runtime Error при этом мы не получим.
- Все числа являются числами с плавающей точкой. В Javascript не существует такого понятия, как "целочисленная арифметика".
- Фактические аргументы в функцию автомагически передаются по значению, если они примитивных типов, и по ссылке, если они объекты. Даже не так. Абсолютно всё передаётся в функции по значению. Просто для объектов (и только для них) эти значения - ссылки. Просто почитайте вот это обсуждение на stackoverflow.
- Ах, да, несмотря на то, что у нас есть примитивные типы данных (которые передаются в функции по значению), мы всё равно можем вызвать у них методы, даже у литерала. Например, `"ababa".localeCompare("babab")` или `(9).valueOf()` (при этом вызвать метод сразу на числовом литерале нельзя, это синтаксическая ошибка). Потому что яваскрипт автомагически превращает объект примитивного типа данных в полноценный объект-обёртку в этом месте (и только в этом месте). То есть, "ababa" становится результатом выполнения `new String("ababa")`.
- Есть два способа объявить обычную функцию, стрелочные функции имеют очень тонкие, но значимые отличия от семантики обычных функций, стрелочные функции можно объявить минимум тремя разными способами. Кроме этого, функции, генераторы, асинхронные генераторы, асинхронные функции и асинхронные стрелочные функции выполняются разными способами. Ладно хоть это ожидается. Кроме стрелочных функций, которые обещали сделать просто синтаксическим сахаром, а сделали отдельным классом функций. А ещё у нас есть "методы" "классов", которые добавляют ещё больше сложностей в и так переусложнённую систему callable'ов.
- Date.getMonth() возвращает значения от 0 до 11.
- В объекте Date есть метод parse, но он парсит только RFC2822 или ISO 8601. В нём есть метод toIsoString, но нет метода format, до сих пор. Не хочу тратить время искать другие нарушения принципа наименьшего удивления, их достаточно.
- Даже Typescript это ложь. Он предлагает проверку типов на этапе компиляции и только на ней. В рантайме никакой проверки типов как не было, так и не будет.
- Для ньюфагов, которые нахватались по верхам в университете знаний о том, как должны выглядеть классы объектов, в ES6 добавили синтаксический сахар в виде class, не изменив ничего в нижележащей объектной модели самого яваскрипта. В результате декларации class выглядят как в языке с классической поддержкой классов объектов, но работают полностью по-другому, тем же самым новичкам взрывая мозг в неподходящий момент.
- Однопоточный рантайм by design, и треды никогда в языке не появятся, скорее всего, потому что async и Promise это же так удобно, зачем нам настоящий параллелизм?
Этот выродок существует, только потому что сеньоры не парятся и страдать в принципе давно привыкли, а джунам маркетинг пудрит мозги, заявляя, что он лёгкий и простой в изучении. В итоге толпы людей сфокусировали внимание на Javascript вместо того, чтобы программировать на нормально разработанном языке программирования, от профессионалов для профессионалов, например C++, C, Haskell, Java, C#, в конце концов, Scala, Common Lisp, Erlang! Я программирую на нём, только потому что за это платят деньги, и спрыгну в другой домен при первой же возможности.