Несколько лет назад на JSConf 2018 выступил Райан Даль, создатель Node.js. Его доклад вызвал сенсацию, он затронул много актуальных проблем и поднял громкий хайп, не оставив равнодушным практически никого, кто связан с серверным программированием. В его обсуждении бэкэнд программисты разделились на два лагеря: одни отстаивали Node.js, другие прочили ему скорую смерть.
С момента выступления Райана прошло немногим больше двух лет, а в IT это целая эпоха, за время которой может поменяться еще не все, то очень многое. Давайте вспомним этот доклад и попробуем посмотреть, что изменилось с тех пор, кто был прав.
Немного про Node.js
Однажды, когда Райан загружал фотографии на Flickr, он заметил необычную вещь — индикатор, который наглядно показывал процесс загрузки фотографий на сервер. Сейчас никого не удивить прогресс-баром, а тогда такие интерфейсы еще не были распространены и, обычно, пользователь наблюдал гифку с банальными песочными часами, которые просто крутились и не давали никакой информации об оставшемся времени завершения операции.
Тогда он задумался о том, что веб-сервер должен уметь обрабатывать одновременно несколько задач. В то время Райан разрабатывал модуль для Nginx, где все работало асинхронно, и пришел к выводу, что эффективнее всего реализовать событийно-ориентированную систему, которой и стала платформа Node.js.
Первоначально среда называлась web.js, но ее возможности применения оказались намного шире, чем обычный веб-сервер, и потому платформу переименовали в Node.js. Готовый проект был представлен Райаном на JSConf 2009, 45-минутное выступление сорвало аплодисменты:
Система быстро получила признание и стала невероятно популярной. Помимо асинхронности у Node много других преимуществ, ее можно использовать как еще один слой абстракции над уже существующим бэкэндом и не переписывать серверную часть заново. Высокая скорость работы и хорошая масштабируемость позволила строить высоконагруженные системы, например, приложения для работы сетевых магазинов, не падающих даже в период сезонных распродаж, когда простой системы может лишить очень существенной части годового дохода.
Не обошлось без проблем, в частности было не просто найти разработчиков с подходящим бэкграундом. Чаще всего причины: «I HATE NODE.JS!!!1111oneone», они проистекают как раз из того, что кажущаяся простота языка привлекает программистов, которые ранее не занимались разработкой для серверов. На JS обычно писали фронтэнд, а там решаются совсем другие задачи. С проблемами сталкивались и разработчики на Java, потому что у них было предубеждение: «На языке называющемся JavaScript, я программировать смогу без проблем!», что на деле было совсем не так просто. Оказалось, что легче других с задачей программирования на JS под Node справляются программисты, работавшие на платформе .Net. Более того, в момент развития Node дотнетчики испытывали некоторые трудности с востребованностью, а программистам JS для бэкэнда хорошо платили.
Сам же Райан через некоторое время после завершения разработки, примерно в 2012-13 годах, увлекся языком Go и надолго отошел от всего, связанного с Node.js, потому что этот язык полностью устраивал его по возможностям и быстродействию, а позже он увлекся нейронными сетями.
Критика Node.js его создателем
Примерно за полгода до конференции JSConf 2018 Райан Даль решил попробовать работать со своим детищем, спустя почти 10 лет с момента его создания. Нельзя сказать, что он был доволен тем, что увидел. Несомненно, проект сильно развился, но во время разработки Node.js Райан был слишком зациклен на решении проблем ввода/вывода, потому допустил некоторые ошибки, которые потом превратились в системные проблемы. Поскольку платформа стала чрезвычайно популярной, то уже поздно было что-то глобально менять, не поломав все зависимости и совместимость.
Райан и раньше очень критично отзывался о всем программном обеспечении, не только о Node.js. В 2011 году он устроил небольшую «пятиминутку ненависти» на Google+. Сама соцсеть давно закрыта, но интернет все помнит. Перевод его слов можно прочитать здесь: Я ненавижу почти всё ПО. А за год до выступления в 2018 рассказывал о том, что: «Для серверов я не могу представить другой язык кроме Go». Забегая вперед, он действительно начинал писать на Go, «убийце node.js», но потом перешел на Rust.
Потому критичный тон его доклада в 2018 году никого особо не удивил, а свежий взгляд создателя платформы снова поднял актуальность некоторых проблем.
10 Things I Regret About Node.js
Давайте вспомним основные тезисы, которые были в нем рассмотрены, а потом сравним с тем, как обстоят дела на данный момент.
1.
Отсутствие Promises, от которых отказались на начальном этапе разработки.
2.
Проблема с безопасностью. Приложение на Node.js получает доступ к локальному диску, сети и вообще ко всей системе сразу.
3.
Сложная и устаревшая система сборки, от которой давно уже все отказались.
4.
Излишне громоздкий package.json.
5.
Семантика платформы несовместима с браузерами
6.
Централизованный репозиторий для модулей.
7.
Команда подключения модуля не требует обязательного указания типа файла, что может приводить к путанице.
8.
Использование index.js, по аналогии с index.html, привело к усложнению загрузки модулей и перестало быть необходимым после поддержки package.json.
Забавно, что в обсуждениях выступления не раз упоминали, что количество сожалений в докладе не соответствует количеству сожалений заголовке, но надо учесть, что Райан очень сильно волновался, его заметно потряхивало в самом начале речи. Более того, он не раз отмечал в своих интервью, что является программистом, а не медийной персоной, сожалел о том, что каждый его пост в блоге «привлекает сотни комментариев» и «теперь надо аккуратнее высказывать свое мнение», потому что сообщество часто понимало его слова слишком буквально.
Анонс Deno
После перечисления недостатков Node.js Райан представил свой собственный проект среды выполнения JS на сервере, последовательно перечисляя его преимущества, в сравнении с Node:
1.
Безопасная песочница для выполнения кода, с предоставлением только необходимых привилегий.
2.
Упрощенное использование модулей, с загрузкой по прямым ссылкам и хранением в локальном кэше, который не будет обновляться до тех пор, пока не будет дана специальная команда.
3.
Полная поддержка TypeScript.
4.
Единственный исполняемый файл без лишних связей
5.
Deno позволяет нативно исполнять код на разных языках, в зависимости от того, какой удобнее для конкретной задачи.
6.
Падение приложений при Uncaught Errors, асинхронные операции будут возвращать Promise, большая совместимость с браузерами.
Кроме перечисленного Deno будет использовать ES Modules, которых тогда тоже не было в поддержке Node.
Что изменилось в Node.js
Доклад вышел неоднозначный, потому он и поднял такой шум в сообществе. С одной стороны, замечания были справедливы. С другой, не все они настолько критичны, что требуется все бросить и писать новую среду.
Пожалуй, самым справедливым было упоминание проблем с безопасностью. У Node.js нет песочницы, которая закроет сервер от запущенного приложения. Эта проблема так полностью и не решена до сих пор. Доступ в сеть можно закрыть фаерволом, доступ к диску и другие полномочия — ограничить через запуск из контейнера, но это сторонние решения, которые не везде могут быть удобны.
Упомянутые в докладе проблемы с выполнением асинхронного кода, на данный момент более-менее решены. Конечно, было бы лучше, если бы Райан не удалил Promises в 2010 году, посчитав, что они слишком все усложняют, но сейчас многие системные библиотеки уже предоставляют этот функционал, не говоря уже про сторонние. Появилась возможность запускать скрипты параллельно с помощью workers, большие компании, такие как Microsoft и Alibaba, разрабатывают свои версии Node с многопоточностью.
От GYP так и не избавились, это наследие будет с Node еще долго. Ссылки url, совместимые с браузером, уже не засунуть, зато, с некоторых пор Node поддерживает ES-модули.
Разрешение зависимостей сложное и работает не так как в браузере, но работает, что самое главное, хоть и не без некоторых проблем. А появление механизма package-lock.json сводит их к минимуму.
NPM сильно эволюционировал с 2012 года. Хотя, надо заметить, эволюция была болезненная и подталкивали ее проблемы типа набившего оскомину left-pad. Но пакеты уже не исчезают просто так, есть несколько уровней аудита безопасности и возможность ставить пакеты из разных источников. Хотя до сих пор ничего не мешает разработчику залить на github правильный код, а в npm код с эксплойтом.
Проблема с index.js выглядит скорее надуманной, чем реальной, как и отсутствие расширений при подключении модулей. Складывается впечатление, что он наспех придумал половину аргументов. Кстати, так и было, подробнее в конце статьи.
Стоит признать, что практически все эти проблемы были решены, и весьма успешно. Сам Даль отстранился от развития проекта, с 2012 года он не имеет отношения к Node, и его доклад выглядит довольно субъективным, где недостатки платформы преувеличиваются в пользу его собственного детища. Таким образом, это выступление больше похоже на рекламу своей разработки, а не на разоблачение Node.js.
Справедливости ради надо заметить, что активно развитие Node сильно сдерживается энтерпрайзом, в котором такое огромное количество легаси-кода, что избавиться от него слишком дорого. Это давно вызывает серьезные проблемы, когда Linux надо обновлять, а под новую систему не удается собрать все модули и рано или поздно приходится переписывать огромное количество кода, тратя на это много времени и денег. Большие корпорации могут позволить себе выделить на это ресурсы, но небольшой хоббийный OpenSource проект будет брошен, если у разработчика не будет времени на его обновление.
Тем не менее у Node.js огромное комьюнити, и оно помогает программистам разбираться со множеством проблем, хотя порой разработчики расставляют приоритеты не так, как хотелось бы сообществу, и потому развитие проекта идет неровно. Возможно, что рано или поздно Node окончательно упрется в те изначальные недостатки, которые описывал Райан, и решить их будет уже невозможно. Но для IT это не первый раз, когда приходится глобально что-то менять. Например, Flash, успешно похоронили, без особых хлопот.
Развитие Deno
Вскоре после доклада, сообщество быстро разгадало анаграмму Node-Deno. Даже прозвучали шутки, что когда-то будет написан проект под названием Done. Но шутки шутками, а к чему же пришло развитие Deno?
Во время доклада Райан честно сказал, что на данный момент Deno экспериментальный прототип и не предлагается как альтернатива Node
Но с тех пор прошло уже больше двух лет, весной прошлого года, наконец-то, появился релиз под номером 1.0.0.
Как уже упоминалось выше, проект начинался на Go, но потом был переделан на Rust. Проект хоть и перестал тормозить, как в начале, но так и не показал преимуществ по скорости. Работа с TypeScript стала быстрее, сказались оптимизации, которые внесла команда, потому что в момент презентации запуск транслятора TS занимал целую секунду. Решено это было, как Райан и предполагал в своем докладе 2018 года, с помощью снимков состояния движка.
Платформа совершенно не совместима с Node и задумывалась не как абсолютная замена, но как альтернатива, исследовательский проект, эксперимент, подсказывающий разработчикам другие пути развития подобных решений.
На данный момент Deno состоит из следующих частей: обертка из Typescript/ Javascript, над движком V8, который является песочницей, обеспечивающий интерфейс между слоем TS/JS и Rust Backend (серверная часть имеющая доступ к файловой системе). Многопоточная работа обеспечивается с помощью Tokio — асинхронной среды, отвечающей Rust, отвечающая за создание и обработку событий, с помощью конструкций «Rust Future», аналога «Promise» в JavaScript.
Среда изначально безопасна, по умолчанию не имеет никаких прав доступа. Для предоставления нужных привилегий, надо запустить платформу с определенными опциями командной строки. Решение неоднозначное. Рано или поздно, разработчикам может надоесть прописывать в скриптах бесконечные опции, потому что в крупных проектах их будет очень много и запускать будут «--allow-all» по дефолту.
При необходимости Deno позволяет вызывать программы на том языке, который удобен для выполнения каких-то отдельных вычислительных задач.
***
На данный момент уже вышла версия релиза под номером 1.7. Но все еще не слышно, чтобы какая-то крупная компания отказалась от Node.js в пользу Deno. Мы даже сделали образ в маркетплейсе для node.js
Проект Deno развивается на энтузиазме, сам же Райан сейчас работает в Google и занимается тем, что ставит задачи перед инженерами, занимающихся нейронными сетями и глубоким обучением.
Кто-то считает, что у Даль развился комплекс первого выстрелившего проекта, когда Node.js, совершенно неожиданно для Райана, почти сразу получил признание и очень резко набрал популярность. Но, скорее всего, он из тех людей, которые не могут сидеть без новых идей и терпеть несовершенства в своем собственном изобретении.
Хотя Даль начал работать над Deno задолго до выступления на конференции в 2018 году, первоначальная тема для него была совсем другая. Он планировал выступить с докладом по машинному обучению, которым занимался последние несколько лет. Но не успел вовремя подготовиться и тема его выступления была снята буквально за пару дней до конференции. А поскольку он понимал свой вес в сообществе и то, как зрители будут ждать его выступления, то за день или два ему пришлось очень сильно постараться, чтобы найти новую достойную тему, оправдывающую ожидания публики.
Так что может он и не задумывал провозгласить «убийцу Node.js», а просто поторопился с подготовкой нового доклада. Хотя ему таки удалось поднять очень изрядный шум, возможно куда больший, чем темой про глубокое обучение.
yurec_bond
То есть его смущают технические проблемы, а то что Node.js сыграл огромную роль в дальнейшей популяризации одного из самых ужасных языков програмирования — его совсем не смущает.
spiceginger
Вот как с языка снял :)
TAPAHbl4
Ну JavaScript — это прежде всего реализация спецификации ECMAScript, так что, думаю, прежде всего вопросы к спецификации и её авторам
andreymal
ECMAScript (1997 год) — это прежде всего попытка составить спецификацию ранее появившегося JavaScript (1995 год), так что вопросы прежде всего к тем, кто потратил на дизайн языка всего десять дней
defaultvoice
А что такого уж ужасного в JS есть по состоянию на 2021-й год? Или вы по привычке уже хейтите?
defuz
Чему там равна сумма двух пустых массивов по состоянию на 2021 год? Все еще пустая строка?
defaultvoice
А чему она ещё может быть равна, при условии, что это язык со слабой типизацией и неявным приведением, где операция сложения определена для чисел и строк?
andreymal
Вот вы сами и ответили на свой вопрос
defuz
То есть вы считаете логичным и правильным такое поведение, если у языка слабая типизация?
defaultvoice
Я считаю неявное приведение типов в таком виде злом, как и слабую типизацию вообще. Но тут есть один момент — данные обычно приходят откуда-то из внешнего источника, над которым контроля как такового нет и не может быть by design, если же проверять все типы в рантайме, мы и так не особенно шустрый веб превратим в ужаснейший лагодром, так что с этим можно только смириться. Во время же написания кода, мы заранее знаем, что в JS всё это — суровая реальность и что этот момент можно сгладить, используя TypeScript
andreymal
Ничто не мешает один раз десериализовать/распарсить внешние данные в правильный тип и потом работать с точно известными типами. Во всех нормальных языках так делают.
Вообще-то в JavaScript как раз постоянно проверяются типы в рантайме… Есть оператор
instanceof
, есть функции вродеArray.isArray
, а если вы подсунете куда-нибудь браузеру неправильный тип (напримерdocument.body.appendChild({})
) он вам в ответ ругнётся о том, что тип переданного объекта не Node, например.Zenitchik
Кто в 2021 году складывает пустые массивы? По прежнему наркоманы?
Regis
eugene08
превед, пихтон! В питоне, что удивительно, так же:
? python
Python 3.8.6 (default, Jan 9 2021, 17:02:36)
>>> [] + []
[]
dakuan
Раз за столько лет не исправили, видимо, кто-то складывает)
P.S. А почему именно пустые? Можно подумать, с непустыми массивами ситуация лучше.
AlexSpaizNet
JS не перестает удивлять =)
DDroll
Чем меньше ты в чем-то разбираешься, тем больше в нем для тебя удивительного) Только в случае с JS, все любят рассуждать о нем с видом экспертов. Советую почитать хотя бы базовую документацию о правилах приведения типов в JS, удивительного в мире станет меньше.
dakuan
Знание причин, из-за которых так получается, не делает саму систему типов JavaScript более логичной. Хороший язык должен быть предсказуемым и интуитивно понятным. А тут возьмите любого программиста (не знакомого с JavaScript), и попросите его предсказать результат сложения 2 массивов — гарантирую, что среди предложенных им вариантов, не будет правильного.
Но тут главная проблема-то не в этом, а в том, что такие вещи маскируют баги.
Zenitchik
Сперва докажите, что такое бывает.
Гарантирую, он скажет, что так не делают.
ZiggiPop
Haskell же!
dakuan
Что именно? Идеального языка пока нет, к сожалению. Языков с более логичной системой типой хватает.
Так проблема и заключается в том, что язык позволяет такую конструкцию. И в определенных случаях это может привести к возникновению багов, которые будет трудно обнаружить.
Ну или возьмем другой пример:
Строки в числа тоже никто не преобразует?)
Zenitchik
Что у термина "интуитивно понятный" есть физический смысл.
Эти определённые ситуации отсекаются проверкой параметров. Да, в отличие от языков со статической типизацией, у нас нет для этого встроенного инструмента. Это неудобство.
aakhamef
PHP.
DDroll
Интуитивно понятно — означает, что после нескольких лет, проведенных в работе с определенной средой и языками, многие вещи вы можете предсказать без документации. Интуиция === бессознательный опыт. Для меня, например, интуитивно понятны «дикие» для вас примеры из JS, которые вы приводите. Или вы всерьез думаете, что если показать условному прохожему-не программисту с улицы программу на Go и программу на JS, он воскликнет, «о, ну тут все ясно, как элегантно», а на JS начнет плеваться? Все дело в знаниях, опыте и привычках.
Nordicx86
я плохой программист, но программу на Go я начал читать через 30-40 минут уже легко и понимая что и как… а Вот JS — забрал пару недель на понимание…
из Опыта в основном Си и Verilog
dakuan
Я такого не утверждал нигде. Для прохожего непрограммиста обе программы будут выглядеть китайской грамотой. А вот прохожий программист, скажем, на C++ (или Java или Python — неважно) скорее всего правильно поймет пример на Go, но пример с массивами на JS вызовет у него недоумение. Я бы, например, предположил 2 варианта: либо конкатенация, либо исключение, если операция сложения не определена для массивов. На деле же имеем третий вариант: код выполняется без ошибок, но возвращает бессмысленный результат.
AFelix
— Олег, почему у вас по велосипедной дорожке ползёт одноногая улитка с однолопастным глазом на подбрюшном хвосте?
— А что вас смущает?
— М… Всё.
— Это потому, что вы документацию на эту улитку не читали. Прочитайте.
— Я читал документацию. Вы правы, там ясно и чётко специфицирована одноногая улитка с однолопастным глазом на подбрюшном хвосте. Но…
— Что но? Вам лишь бы прикопаться?
— Да нет, конечно, так-то мне в целом всё равно… но давайте уточним. Вас вот совершенно не смущает одноногая улитка с однолопастным глазом на подбрюшном хвосте потому, что кто-то описал это чудо биоинженерной мысли в документации, а затем реализовал?
— Да, а что? Повторю: читайте документацию, не надо удивляться. RTFM, lamo.
— Ясно, спасибо. Удивляться я не буду.
aakhamef
Это копипаста или Ваш ориджинал? (В любом случае аплодирую!)
AFelix
Ориджинал. :)
Zenitchik
— А что Вы имеете против одноногой улитки с однолопастным глазом на подбрюшном хвосте? Почему это чудо биоинженерной мысли вообще должно кого-то смущать (равно как и любое другое чудо биоинженерной мысли)?
DDroll
Потому что это не велосипедная дорожка, а испытательный трек для одноногих улиток с однолопастным глазом на подбрюшном хвосте, слизь которых используется для лечения рака. Вы просто так мало ездите на чем-либо кроме велосипеда, что все вокруг считаете велосипедной дорожкой.
AFelix
Я за 20+ лет работы писал на 5+ языках, включая [Node.]js, которому в сумме отдал года четыре, пожалуй. В процессе вёл внутри компании курсы по JS и составил quiz из 30 вопросов, которым выносил голову любому. Собсно, сам на него уже через месяц полностью ответить не смог, настолько «интуитивные» механики языка, ага. Всё ещё считаю JS худшим языком из нынешнего топа.
Это к тому, что вы напрасно пытаетесь загнать оппонентов в комфортный вам шаблон «они просто не пробовали эту вкусную морковочку». Пробовали. А некоторые из моих знакомых и 10+ лет пробовали, потом ушли именно после более глубокого знакомства с другими языками.
Т.ч. нет, мир сложнее и, возможно, морковочку стоит оценивать более критично. Что, конечно, не отменяет простого: вам язык может нравиться настолько, что и фиг с остальным — позиция ничем не хуже других.
Zenitchik
Это очень-очень странно. Человек либо знает язык, либо не знает. Либо вы составили его из 30 вопросов про то, что никогда ни для чего не применяется.
Это мне совсем не понятно. Если человек не способен самостоятельно освоить JS по открытым источникам — значит с ним что-то сильно не так и JS-разработчиком ему не быть.
(то же скажу о любом другом языке)
AFelix
Это… замечательное мнение. :)
defuz
Если наркоманами вы называете всех, кто пишет на других языках программирования, то да – наркоманы.
Zenitchik
Нет, наркоманами я называю тех, кто делает нечто ОЧЕНЬ СТРАННОЕ, а потом удивляется, что результаты получаются странными.
Согласитесь, в языке, в котором сложение не определено для массивов, никому не придёт в голову складывать массивы. И не важно во что они там неявно преобразуются.
sumanai
Раз не определено, то нужно выкидывать исключение, а не приводить к чёрте чему.
prog_f130
Целый холивар сложения массивов, при том что для этой операции определен целый синтаксис Spread-ов. А вы, простите, когда гвоздь забиваете тоже бьете им себе по голове, а потом удивляетесь, почему гвоздь не забит, а из головы течет кровь?
norguhtar
А вам правда нравится синтаксис спредов? Мне вот не очень.
Alendorff
Честно говоря, мне не очень понятно почему люди до сих пор постоянно обсуждают как они в джаваскрипте сложили что-то, что не стоило складывать, и получили нечто забавное. По-моему уже должно было всем давно надоесть в 21 то году. Это как шутить что IE медленный.
nin-jin
Обычно это делается непреднамеренно. Где-то допустили багу, некорректные значения расползлись по всей программе. И в случайном месте мы получаем, внезапно, какой-нибудь
Hello, mr. Object] [object
вместо внятного сообщения об ошибке.Alendorff
Ну не знаю, я не страдаю как-то. Стокгольмский синдром наверное.
Я понимаю проблему, просто на мой взгляд она сильно преувеличена и стала уже избитой шуткой, которой принято попинывать js.
Shatun
Например undefined и null-я видел десятки багов связанных с этим на разных проектах.
Alendorff
а я видел 500 Uncaught exception: java.lang.NullPointerException в ответе от апи десятки раз на разных проектах, что ж теперь джаву за это не любить :) она же не виновата
andreymal
Конечно же виновата в том, что в ней отсутствует null safety, который уже завезли в Kotlin, C# и много куда ещё
Shatun
Так это же примерно половины той же проблемы. И да, жду когда завезут null-safety, как это сделано во многих популярных языках. Но проблема когда у вас есть null которыми оперируют половина внешних зависисостей или когда есть null и undefined-это в несколько раз больее глубокая проблема. И она как раз на уровне дизайна.
norguhtar
Основная претензия к языку это его не консистентность. Просто сравните без учета библиотек и прочего javaScript и тот же Lua. Он просто имеет травмы на уровне дизайна.
domix32
C неконсистентностью PHP сколько лет жили, пол интернета на нем написали.
norguhtar
У PHP между тем на уровне языка не настолько все плохо. Просто для пояснения
В php функция gettype от массива вернет array
В js функция typeof вернет object и что это массив можно узнать только через Array.isArray()
Я вот про такую неконсистентность. Если мы посмотрим что там в lua мы увидим что там схема похожа на js, но она там просто консистентна. Там есть примитивные типы, функции и таблицы. И все. И таких вот особенных типов нет.
Zenitchik
Array — это не особенный тип, а частный случай объекта. Так же как в Lua вместо массивов используются таблицы.
norguhtar
Все бы ничего, если бы им пользовались как объектом. А им пользуются как массивом. И такого внутри JavaScript много и оно не очень логично.
Zenitchik
В Lua тоже пользуются таблицей (с соответствующей метатаблицей) как массивом. И это очень логично. Тут полная аналогия.
norguhtar
В lua таблица расширяется до массива. И массив объявляется как таблица и при обращении к нему сообщается что это таблица. Расширение до объекта не более чем использование в качестве ключей вместо string number и все.
А как в JavaScript? Сам массив объявляется отдельной конструкцией языка, а не как объект. Т.е
В каком месте так же?
Zenitchik
В JS массив — это объект, всё его поведение реализовано в его прототипе, как и у любого другого объекта. Его можно создать конструктором, как и любой другой объект. При обращении к нему сообщается, что это объект.
Это синтаксический сахар. Для объекта, кстати, тоже.
norguhtar
Тут есть два вопроса. Какие из методов объекта массива используется напрямую? И второй зачем это было вообще делать, если практически во всех языках массив или таблица это отдельный примитивный тип?
В итоге мы имеем красивую на бумаге теорию и кривую реализацию. Чем криво? Ну просто практически никто не работает с массивом как с объектом в js.
Zenitchik
В объекте практически нет методов. Это к делу не относится.
У массива есть свойства и методы — как и положено объекту.
Ага! Таблица в Lua — это аналог объекта в JS. Полная аналогия, которую Вы упорно не хотите видеть.
Кстати, в Java — вообще все данные — объекты.
Да Вы что? А как с чем же с ним работают?
Что, свойства не читают и методы не вызывают?
norguhtar
Проблема в том что при этом сначала надо обратиться к нему как к объекту. При этом синтаксический сахар делает так чтобы он не выглядел как объект.
Эмм. Смотрите в lua таблица расширяется до объекта через мета таблицы и синтаксический сахар. А в js объект имплементирует массив через реализацию и синтаксический сахар. Как вообще разные вещи. Первый подход все же в динамически типизируемом языке лучше.
Примитивные типа там все же есть, как и отдельное объявление массивов. К тому же там статическая типизация из-за этого проблемы объект или массив там фактически нет. Если у вас она там появилась, то вы явно злоупотребляете рефлексией.
Обычно с ним работают через скобочную нотацию. И да из-за того что и массив и объект одно и тоже приходится городить отдельные проверки. Причем проверка делается именно для массива. Т.е. мне мало посмотреть объект ли это мне еще надо посмотреть массив ли это. Если считаете что не только для него то я бы хотел посмотреть на пример.
В итоге мы и получаем хотели как лучше, а получилось как всегда.
Zenitchik
Нет. Это Ваше личное искажение восприятия.
А в js объект имплементирует массив через прототип и синтаксический сахар.
Прототип — аналог метатаблицы. Подходы идентичны.
Представьте себе, скобочная нотация в JS используется для любых объектов. Это просто другой способ обратиться к свойству по имени.
А если я буду ждать на вход класс Cat, я бужу использовать проверку именно для класса Cat. Что в этом удивительного?
norguhtar
Эх. Если бы только у меня. Это известная проблема и она возникает у всех. И возникает она от того что массив определяется не как объект, а именно с этим синтаксическим сахаром. И по аналогии с другими языками все ожидают что typeof будет давать им array.
Языки похожи но не идентичны. Объявление методов мета-таблицы выполняется по другому.
Я знаю. Просто разница между lua и js именно в том что lua дает более консистенный подход чем js. Тут дьявол именно в небольших деталях и ожиданиях программистов. В итоге особенностей в js приходится помнить больше чем в lua. От этого происходит частый выстрел в ногу.
Zenitchik
Почему у меня она никогда не возникала?
Это главная ошибка человека, изучающего новый язык. Не ожидай того, чего тебе никто не обещал, и не будешь разочарован.
Чисто синтаксическая разница.
Нет. Примерно то же на то же, просто у JS стандартная библиотека больше.
norguhtar
Ну потому что видимо читали полный референс. А про не ожидаемое поведение не я же один тут пишу.
Именно она и дает проблему. Крякает как утка значит это утка. Js сильно похож на другие языки особенно в части создания массивов вот и результат. Синтаксис lua прямо указывает что массив таблица, просто за счет использования одинаковых фигурных скобок. Если бы это было так же в js или банально там бы он объявлялся через конструктор объектов проблем было бы меньше.
Больше. Просто смотрите в lua
И тут взрыв
в javascript
WAT?
Lua мне явно говорит слыш чувак я так не умею. А JavaScript делает какую-то дичь. В итоге даже случайная опечатка или не внимательность в коде может легко приводить к неопределенному поведению и сложно уловимым ошибкам. И про это приходится помнить. Плюс многие наоборот начинают таким пользоваться, что приводит опять же к странному коду.
Zenitchik
Не полный, а более-менее полный для начинающих. Я же не с полного референса учиться начинал.
И я интуитивно полагаю, что люди изучающие язык, изучают язык, а не "изучают как писать программы копипастом".
Все эти отсылки про "ожидаемое поведение" — выглядят как перекладывание с больной головы на здоровую. Язык изучать надо, а не "ожидать" от него чего-то.
Да объявите, кто же вам мешает?
В соседней ветке длинный предлинный диалог, сводящийся к тому, что здоровые люди так не делают.
norguhtar
это выглядит как в том анекдоте.
Хорошо бы, но люди ожидают вот и все. Делать защиту от дурака это весьма полезная тема и многие проблемы в js именно от того что авторы не подумали или не сделали.
Ну тут есть один момент, средняя квалификация по больнице у кодера js низкая. И так делают.
Zenitchik
Они на начальном этапе на самом деле много что подумали и специально не сделали. Из рассчёта на подход "не делайте так". Вы же знаете, почему в JS приватных свойств не было?
Полагаю, проблема не в языке, а таки в самих кодерах. Не имейте дела с плохими кодерами — и будет вам счастье.
norguhtar
Вот в lua я вижу что люди думали. В js ощущения нет.
Если бы все кодеры были хорошими мы все еще писали бы в машинных кодах.
Zenitchik
Если бы это было так, не процедурный подход не появился бы.
Zenitchik
*процедурный подход бы не появился.
(не успел исправить)
aakhamef
У строки и числа тоже есть методы. Почему их не определяют как объект?
Zenitchik
Строка и число при обращении к методам неявно преобразуются к классу-обёртке. А экземпляр класса-обёртки — это объект.
Если хотите можете попробовать
?
?
?Экземпляры этих классов не являются значениями примитивных типов.
Wendor
А что ужасного в JavaScript?
SadOcean
Да вроде все то же, что и раньше — слабая типизация, неявное поведение, отсутствие возможности низкоуровневой работы, привязанность к браузерам(фрагментация, полифилы), отсутствие инструментов выражения спецификаций (типы, интерфейсы) которые нужны для библиотек, медленная работа.
Не зря же пром стандартом становится тайпскрипт, внедряется WASM, а люди изобретают тонны решений для этих проблем разной степени успешности.
По поводу производительности — не поймите неправильно, V8 — чудо инженерной мысли, просто это концептуальное ограничение. Так то и на реализацию ООП через ссылки в java и C# говорят что она медленная.
Wendor
Имхо, это все крайне споные моменты. Претензии к нишевому языку за то что он не такой как другие универсальные языки. Или давайте уж кинем претензию другим нишевым языкам. Lua, Python, PHP, Perl, Лисп. А можно еще и bash'у в догонку.
Не поймите неправильно — я разделяю ваши сожаления об отсутствии типизации, низкоуровневой работе (хотя в контексте ноды, эту проблему можно решить модулями) и прочем, но давайте не перегибать. Все равно что утверждать киянка плохой молоток и портится от гвоздей.
zhaparoff
Так в этом-то и был изначальный посыл, что пытаются использовать нишевый язык везде где только можно, натягивая сову на глобус. А node.js оказался просто вундер расширителем совы, позволяющим растянуть ее до невиданных доселе размеров и форм каждому встречному. Но суть процесса от этого слабо поменялась и системные противоречия никуда не делись. Так что значительная часть глобусов до сих пор с огромным трудом встраивается в сов, и требует крайней осторожности, чтобы не нанести непоправимого ущерба ни тем, ни другим.
А по теме, самый лютый с моей точки зрения пример: переформатировал код, чтобы читался полегче, и все сломал. Простым переносом строки… Вот где, простите, ж*па.
nin-jin
Ну вы ещё слова в названии функции не camelCase пишите, а разделите пробелами для лучшего чтения, а потом удивляйтесь, что всё сломалось.
transcengopher
Постойте, но ведь разница между вашим предложением и переформатированием кода в том, что вы добавляете whitespace туда, где его раньше не было, а zhaparoff — менял количество различных символов whitespace там, где они и так уже были.
nin-jin
Он добавил перевод строки там, где его не было.
transcengopher
Перевод строки, согласно всем конвенциям, является whitespace, как и пробелы. А так как JavaScript относится к семейству языков, где whitespace не несёт синтаксической нагрузки, то автоматическое добавление
;
в конец строк кода является очередным misfeature.Для примера, я пока не встречал специально настроенного линтера, где бы разрешено было писать код так, чтобы эта фича интерпретатора имела возможность примениться. Там, где эта фича хоть иногда срабатывала, просто не было линтеров (на них забивали).
Zenitchik
Да, это бесспорный недостаток языка.
nin-jin
Это не так.
Wendor
Я лишь пытаюсь сказать что сам язык не ужасен. :-)
igor-D
Причем тут «одного из самых ужасных языков»? Он вроде не про С++ пишет)
Если серьёзно- js местами выдает странные вещи, но до уровня запутанности, переусложненности, странностей дизайна, отсутствия нормального ООП, дубовости компилятора (но тут просто js не компилируется) — вот этого всего набора характерного для С++, ему очень далеко. Понимаю, что кому как, а по мне именно js вполне себе неплох, но очень хотелось бы нормальное управление потоками и возможность работы со строгими типами побайтовыми (uint8, int16 и т.д.) чтобы было в нем.
oq0po
Надеюсь услышать Торвальдса на его выступлении.
Vadiok
Однако же Торвальдс начинает посматривать в сторону Rust