Как стать автором
Обновить

Комментарии 287

НЛО прилетело и опубликовало эту надпись здесь
Если не ошибаюсь, то уже был этот перевод на хабре.
Ну ничего страшного, статья-то замечательная :) Не грех и еще раз посмеяться. Тут как раз соседний топик «Зачем нам JQuery?», так что весьма ситуативно получилось.
когда до сих пор работаешь с adobe flex, имеешь немаленький опыт в ооп и понимаешь, что охватить это все нереально, чтобы сменить специализацию, то становится не очень смешно.
Очень ошибаетесь. При желании это все очень быстро учится. Главное — практика.
Не, был перевод как-раз того, по чьим мотивам это написано. Перевод
Это можно про почти любую технологию так написать. И в конце приписать «я возвращаюсь к программированию на ассемблере».

Факт в том, что все упомянутые в посте вещи — это IMHO необходимый для 2016 года минимум, которым каждый сильный инженер должен если и не владеть, то хотя бы иметь представление о. Это не rocket science.
Проблема в том, что этот минимум весь разношёрстный, выпущенный разными вендорами, каждый со своими особенностями и без какой-либо стандартизации. Плюс постоянно висящий в стадии «почти готово» (это я про RC5 для Angular 2), где каждый последующий RC не обратно совместим с предыдущим. Жесть же, менять архитектуру роутера на стадии кандидата в релиз. Она по уму и на бете то уже не меняется.
И нельзя так написать про любую технологию, в том же C# нет такой жести, новые версии обратно совместимы с предыдущими, интерфейсы официальных компонентов пишутся по одному паттерну, есть нормальная документация. И с NuGet нет такой жести, какая бывает с Npm пакетами, где выход новой минорной версии компонента может ломать всё приложение.
Потому что молодое еще. Не успело стандартизироваться, мало серьезных научных работ, не устаканилась даже терминология. Это еще не стало частью computer science, но станет. Так всегда бывает поначалу. Например, с promises и асинхронным программированием уже меняется дело к лучшему (см. частично https://github.com/kriskowal/gtor/blob/master/README.md).
Молодое? JS в 1995 появился, в один год с Java и на 5 лет раньше C#.
Для больших и сложных приложений его стали только в последние годы использовать. Отсюда и взрыв технологий и интереса к языку, и проблем сопутствующих. В 95 году это был просто встраиваемый скриптовый язык, по типу bash. Никто не предполагал, что это будет основой будущей «операционной системы интернета».
Простите заранее за возможно некорректный вопрос, но за что минусы комментарию выше? Разве это не верная точка зрения?
Не совсем. Доля правды есть, но… Не совсем.
Да, теперь мне сразу стало всё понятно. Спасибо!
Я не совсем понял, при чем тут JS и когда он появился? Речь-то не о JS, на его месте мог бы быть любой другой язык — хоть тот же Python. В JS нет ничего принципиально отличного от других языков (ну разве что event loop, встроенный в язык, в то время как в большинстве других он идет отдельной библиотекой; плюс прототипное наследование, насчет которого даже идеологи ecmascript сдались в итоге и ввели в обиход ключевое слово class, зарезервированное, впрочем, с самого 1995-го года, потому что уже тогда что-то подозревали).

Речь идет о стеке приемов и технологий. Этот стек я выше имел в виду, когда говорил о том, что он войдет в будущий computer science, как 40-50 лет назад (или когда там) в него вошли алгоритмы сортировки или концепции функционального программирования, например.
Насчет идеологов это вы зря. Как раз-таки многие идеологи ECMAScript против классов. К примеру, Дуглас Крокфорд вообще не использует классы (btw, благодаря нему в JS появился `Object.create`).

Вот список статей, обосновывающих, почему классы в ES6 это кривой костыль, создающий проблемы, а не решающий их: Not Awesome: ES6 Classes

Или вот: How to Use Classes and Sleep at Night
IMHO классы не доделали просто (еще не доделали?). Навскидку, например, автобиндинг this для «методов», объявленных в «классе», был бы весьма кстати (чтобы можно было в том же React-е писать onClick={this._myOnclick}, по аналогии с тем, как в Python автобиндится self при взятии ссылки на метод у объекта), а его нет. Ну или поддержка синтаксиса для «декораторов», как топикстартер упоминал.

Другой пример: в JS в catch() у try-catch нельзя фильтровать по «типу» исключения. Всегда пишется просто catch (e). Почему? Возможно, из-за того, что до появления концепции и конструкции async-await поверх промисов мало кто исключения в JS использовал широко (в силу асинхронной природы большинства операций исключение, выброшенное в одном месте, очень сложно поймать в правильном месте). Для фронтенда это и не было особо важно: во фронтенде инвертированный поток управления, но для серверного языка ИМХО исключения очень важны и удобны! К счастью, async-await вдыхает новую жизнь в исключения в JS и их поимку — она стала предсказуемой:

try {
a = await aaa();
B = await bbb();
} catch (e) {
Поймали!
}

В функциональных языках и без исключений как-то живут. А серверные языки сейчас как раз в сторону функциональщины двигаются, да и не любят там исключения в общем-то, всё чаще пишут что-то подобное (если интересно) и тихо ненавидят яву за её checked-exceptions:


Try<MyResult> attempt = Try.of(this::doMyWork);
MyResult result = attempt
    .recover(this::tryToRecover)
    .getOrElse(myDefaultResult);

Или просто сразу пишут stateless и повторяют попытку в случае исключения.


И таки да, вроде как вот такая конструкция будет работать в JS: onClick={::this._myOnclick}

И таки да, вроде как вот такая конструкция будет работать в JS: onClick={::this._myOnclick}
Таки нет, к сожалению — убрали её из черновиков стандарта.
Кто вам сказал такую глупость?

О, прикольно, вернули в stage 0. В какой-то момент его вообще реджектили просто.

В какой момент ::this биндит себя к функции? В момент вызова или в конструктор как-то перемещается (или какой-то кэш)? Если в момент вызова, то это проблему не решает, ибо — утечка памяти потенциальная — в доках по реакту упоминается, что надо биндить один раз в конструкторе, а не каждый раз при рендеринге.

Не совсем понял вопрос, видимо. Конструкция


bla(::this.bar)

превращается в


bla(this.bar.bind(this));

Не вижу тут потенциальных утечек (во всяком случае, таких, которые не возникли бы при любом другом прокидывании this — через ту же стрелочную функцию, например). Про реакт сказать ничего не могу — не использую его.

Через стрелочную то же самое, верно. Просто метод render(), который при вызове строит представление компонента полностью (включая вложенные компоненты), будет создавать новые функции для каждого из многочисленных событий при каждой перерисовке (что при использовании bind, что при =>). А перерисовка может происходить очень часто, так что использование памяти увеличится, а сборщик мусора будет трудиться больше и дольше.

Может быть, это экономия на спичках, конечно.
Чтоб не перерисовывать часто есть различные обертки, делающие проверку аргументов и пропускающие рендер, если аргументы не менялись. Бонус immutable state.

Здесь речь идёт о том, что когда вы делаете так:


render() {
  <Component onAction={this.handleAction.bind(this)}
}

, то Component при каждом рендере родителя будет получать новый обработчик onAction, а значит должен перерендерится, и так далее. Хотя, на самом деле, обработчик один и тот же, просто .bind(this) на каждый вызов возвращает новую функцию. Для решения этой проблемы и предлагается биндить заранее, можно через стрелочный синтаксис:


handleAction = () => {}
render() {
  return <Component onAction={this.handleAction}
}

либо декоратором (как на свойство класса, так и на весь класс).

Научные работы на какие именно темы здесь нужны, по-вашему?
Например, реактивность (в широком смысле: React, Redux — частные случаи), асинхронное программирование в новом свете (промисы, async-await, бэтчинг), новые подходы к API (GraphQL сотоварищи). Согласен, это все более высокоуровневые вещи, нежели алгоритмы на графах или сортировки, но мне так кажется, что computer science постепенно идет в сторону усложнения концепций.
Если под реактивностью вы имеете в виду FRP, то есть небольшая библиография здесь.

Промисы и прочие async/await давно есть во всяких сишарпах. Уже даже в C++ пришли.

Сколько разных публикаций по асинхронному программированию — не счесть, поковыряйте arXiv.

Что принципиально нового в GraphQL, я при очень быстром прочтении не понял.
чтобы написать todo-list?
Да
> это IMHO необходимый для 2016 года минимум

А сколько элементов этого списка войдут в необходимый для 2017 года минимум?

Можно оценить, например, сравнив с необходимым для 2015 года минимумом.
Да, в каждой шутке есть доля шутки.
Использую js с 2003 года и то что происходит сейчас во многом похоже на лютый треш :(

Ну, как вам сказать. Как ни крути, для серьёзного проекта приходится использовать библиотеки или фреймворки. Чтобы собрать и пожать релиз — нужен какой-то бандлер. И то и другое можно написать самому, но зачем?

Я это понимаю, расстраивает только, что нет стандартов на это, которым бы все старались соответствовать. Webpack замечательная штука, но одновременно с ним появилось ещё 3 аналогичных инструмента. То же самое с фреймворками, есть AngularJs, Angular2, React и 100500 других. С надстройками над js то же самое, TypeScript, CoffeeScript,…
В итоге отрасль дробится на условные «цеха», где все делают одно и то же, но каждый по своему. В итоге реальным профессионалом стать проблематично, появляется новая «фишка» и всех отбрасывает на нулевой уровень. Переход разработчиков с проекта на проект затруднён, вот писал ты 2 года на React, а теперь переходишь на Angular, сколько времени понадобится на адаптацию? Грустно это.
А корень проблемы — сам javascript, который кривой, косой, написанный за полтора дня на коленке и с минимальной библиотекой базовых классов. Это был отличный язык для веба в 90х и начале нулевых, когда верхом искусства был DHTML (dynamic HTML), где с помощью JS можно было показывать текущее время.
Все эти надстройки, описанные в статье, к сожалению, лишь костыли над кривым языком. И меня реально пугает, что его пытаются тащить во всё более серьёзные вещи, типа веб-серверов и микроконтроллеров.

P.S. Чтобы не было недопонимания, под кривизной JS я подразумеваю то, что он изначально разрабатывался для несложных манипуляций с пользовательским интерфейсом. Он изначально не предполагал многопоточности, серьёзных возможностей для работы с исключениями, быстродействия. Он реально был написан на коленке. Как «Ока», практически. А сейчас из него пытаются Камаз сделать.
Ну вы в курсе, да, что языку уже двадцать лет, и он значительно изменился за это время? Мало ли для чего он изначально создавался? Сейчас на нём можно писать приложения любой степени сложности. И не надо рассказывать про быстродействие, 20 лет производителями браузеров были потрачены не зря, интерпретаторы заоптимизированы по самое «не могу». В первую очередь это, конечно, касается es5 (банально — нативные промисы всё еще медленней полифиллов на es5), но и es6 подтягивается.

И отдельно хочется прокомментировать: «Это был отличный язык для веба в 90х и начале нулевых». А сейчас для веба есть еще какой-то язык?
21, если быть точным. И в чём он конкретно изменился? «use strict»; появился?
Сейчас на нём можно писать приложения любой степени сложности используя все те костыли, которые указаны в статье. Хотя это не верно, у JS есть принципиальные ограничение, например он не работает с файловой системой, в самом языке нет такой функциональности, она реализуется за счёт внешних модулей (например в составе NodeJs) и в принципе не реализована в среде веб-браузера. То же самое относится к хранению данных, есть внешние библиотеки, реализующие доступ к LocalStorage браузера и базе данных, но это не часть языка, это именно внешняя библиотека, которая в одних браузерах реализована, а в других нет.
JavaScript — это костыль на костыле, пирамида костылей. Хотите что-то реализовать — не забудьте заглянуть на http://caniuse.com чтобы проверить, где эти костыли реализованы.

Приложения любой степени сложности на, например, упомянутой nodejs можно писать на нативном ES6 безо всех этих костылей. JavaScript сегодня — не только браузер. Тут уже скорее вся остальная появившаяся инфраструктура приводит к появлению костылей для того чтобы в браузере работало "как там".

он не работает с файловой системой, в самом языке нет такой функциональности

Язык и не должен работать с файловой системой сам по себе. Это задача стандартных библиотек.
Сравним C#:
string text = System.IO.File.ReadAllText(@"path/to/file");

и JS:
let text = require('fs').readFileSync('path/to/file');


/offtop
А вам бы действительно хотелось, чтобы JS в веб-браузере мог работать с вашей файловой системой?
Странный аргумент) У C++ также нет библиотеки для работы с фс, это не мешает ему быть одним из самых популярных языков.
Нету сейчас другого языка для веба, к сожалению, поэтому и появляются костыли. Они реально необходимы, потому что без них нормального приложения в 2016 не напишешь. Но костыли никогда не заменят живые ноги, и мне грустно от того, что и попыток создать язык с ногами не особо заметно :(

Всяко лучше, чем дотнет.

Обоснуйте
Он хотел сказать «всяко лучше чем совсем без ног»
Любой язык, которому много лет — это набор костылей. С++, стандарт которого, наверное уже перевалил за 5000 страниц, PHP, создателя которого даже за программиста не считают, Java, ставшая COBOL'ом нашего времени.

Есть. И это Dart.

Вряд ли он в обозримом будущем будет в рантайме браузеров.

В рантайме браузеров будет WASM.

как я надеюсь что в рантайме браузера будет LVM

logical volume manager? Второй версии, надеюсь?

Черт что с моими руками, могли бы и не ехидничать
LLVM конечно же
Дарт умер, но перед этим он успел стать джавой в её худшем проявлении. Что печально.
Он еще возродится в google fuchsia
Только вот при чём тут ОС, если мы о языках?
Fuchsia is reportedly written in Dart
https://en.wikipedia.org/wiki/Google_Fuchsia
А на опеннете читал, что на дарт там будет UI. Ядро на Си
То-то по нем в октябре будет конференция. Вы прямо цитируете пост.
Ну вы в курсе, да, что языку уже двадцать лет, и он значительно изменился за это время?

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

Вот например, одна из фундаментальных особенностей языка — нестрогая динамическая типизация. Для написания DHTML, особенно в середине девяностых, это была киллер-фича: пишем пару строчек и всё волшебным образом работает. Вполне возможно, что именно низкий порог вхождения помог JS приобрести свою популярность на ранних этапах.

Пока двадцать лет веб был относительно простым и дышал романтикой юношеского максимализма, противоположная сторона IT — суровый и серьезный энтерпрайз — также развивался и накапливал опыт. Умные дяди выяснили, что статическая типизация позволяет повысить качество приложений и сократить время разработки: ошибки ловятся компилятором на ранних этапах разработки, автокомплит работает лучше, появляется простор для оптимизаций. Более того, объем кода от этого не только не раздувается, а даже наоборот — современные компиляторы типа C# \ Scala \ Rust могут в большинстве случаев вывести тип самостоятельно, лишь изредка опираясь на подсказки со стороны программиста.

Седые и скучные энтерпрайзеры открыли еще несколько любопытных вещей. Например, если в языке есть средство сделать поля/методы классов приватными, у новичка или невнимательного программиста сокращается шанс случайно напортачить. Если различать и грамотно использовать структуры данных, приложение будет работать быстрее и потреблять меньше ресурсов. А с помощью многопоточности можно ускорить приложение еще сильнее.

Теперь, когда к веб-приложениям предъявляются требования уровня энтерпрайза, было бы вполне логичным перенять этот опыт. Но большая часть сообщества видит в этом только ущемление собственной свободы и протестует с упорством, достойным лучшего применения. Вместо этого изобретается «свой особый путь».

Нужны приватные поля? Вместо этого изобрели новый базовый тип Symbol, который сложно понять и всё равно можно обойти. Вместо потоков — веб-воркеры, без примитивов синхронизации и с урезанными возможностями взаимодействия. Вместо классического наследования — прототипное. Список можно продолжать довольно долго.

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

Сейчас на нём можно писать приложения любой степени сложности.

Можно, но при этом приходится изобретать решения для проблем, которых вообще не должно было возникнуть. Например, как сделать словарь, ключи которого являются объектами? Очевидного способа нет, можно попробовать несколько экстравагантных, каждый со своими особенностями и ограничениями? А если нужно получить слабую ссылку? Увы, никак — есть WeakMap, но он работает немного по-другому.

Особенно иронично, что некоторые типично динамические трюки в JS сделать сложнее, чем в языках, обычно считающихся статически типизированными. Например, как перехватить обращение к любому полю и получить название этого поля в виде строки? В ES6 для этого будет новый класс Proxy, который пока не везде поддерживается и с горем пополам полифиллится. В это же время аналогичный функционал в C# был доступен еще в 2010 году.

20 лет производителями браузеров были потрачены не зря, интерпретаторы заоптимизированы по самое «не могу»

Двадцать лет были потрачены как раз-таки зря: пришлось придумывать решения для проблем, которые в статически типизированных языках вообще не существуют. Результат, безусловно, похвальный — но у пользователя по-прежнему масса возможностей написать код так, чтобы сломать оптимизации.
Нужны приватные поля? Вместо этого изобрели новый базовый тип Symbol, который сложно понять и всё равно можно обойти. Вместо потоков — веб-воркеры, без примитивов синхронизации и с урезанными возможностями взаимодействия. Вместо классического наследования — прототипное.

Тут я с вами очень сильно не соглашусь. Прототипное наследование намного мощнее вашего так называемого «классического». Классы это новая (лишняя) сущность по отношению к объектам — это blueprint'ы объектов — тогда как прототипы придерживаются самого настоящего классического ООП принципа «всё есть объект»: наши прототипы это тоже объекты. То есть, прототипное наследование на деле куда более «классическое», оно проще, оно фундаментальнее. Оно объектное.


Символы точно так же куда более общая концепция, чем приватные поля. Приватные поля — это атрибут «классов», они не имеют смысла в рамках модели, в которой классов нет (в JS классы это лишь сахар для настоящих объектных прототипов — для тех несчастных, кто не освоил их — чтобы сгладить переход из других языков).


Например, символы позволяют делать свойства без строкового имени вообще (анонимные), исключая конфликты с существующими полями:


field = Symbol () 
obj[field] = ...

Что позволяет расширять объекты мета-информацией, доступной только тем, кто в ней заинтересован, не вступающей в конфликт с чем-то еще. Скажем, вместо метода .toString () у объектов, процедуры распечатки объектов могли бы экспортировать соответствующий символ. Вот как это сделано в библиотеке string.ify например:


Boolean.prototype[Symbol.for ('String.ify')] = function () {
                                                   return this ? 'yes' : 'no' }

String.ify ({ a: { b: true }, c: false })
//         '{ a: { b: yes }, c: no }'
Оно-то мощное, но в нём напрочь отсутствует такая удобная штука, упрощающая понимание кода и обнаружение ошибок, как типизация.
Мы говорим «класс» — подразумеваем «тип», т.к. объявление классов и интерфейсов — это по сути объявление типа.
Когда тип объявлен, мы можем указать, что вот эти переменные содержат объекты именно данного типа. Мы можем выполнить что-то вроде isInstance(), тем самым быстро проверив, содержит ли переданный нам объект нужный набор методов и свойств. У нас упрощается генерация документации, ведь мы можем указывать тип и пользоваться инструментами вроде jsdoc.
С нашим кодом становится гораздо проще работать статическим анализаторам и IDE, тогда как в случае использования прототипов для чего-то кроме эмуляции классов даже WebStorm от JetBrains начинает путаться, выводя неверные подсказки.
В общем, для крупных проектов отсутствие простого способа указания типов очень неудобно.
Прототипное наследование намного мощнее вашего так называемого «классического».

В этом и суть проблемы: хорошо в теории, плохо на практике. «Классическое» наследование близко к железу — можно определить адрес каждого поля на этапе компиляции и потом пользоваться очень быстрыми операциями доступа к памяти по смещению.

Прототипное же наследование предполагает, что пользователь может в любой момент творить грязные трюки, расширяя прототипы или вообще подменяя их. Несмотря на то, что большинство пользователей в здравом уме этого не делает, компилятор по стандарту все равно вынужден обмазывать всё бесконечными проверками и инлайн-кешами. Приходится делать выбор между сложностью устройства компилятора, расходом памяти и производительностью. И кому нужна эта «мощь» такой ценой?

Хорошая аналогия — рекурсия в ФП. Отличная математическая концепция, хорошо позволяющая описать любое циклическое вычисление. По факту же, в компиляторе без tail call optimization пользоваться ей опасно.

Cимволы позволяют делать свойства без строкового имени вообще (анонимные), исключая конфликты с существующими полями

Сначала поставили прототипное наследование во главу угла, а теперь героически решаем возникшие проблемы с помощью символов.

Что позволяет расширять объекты мета-информацией, доступной только тем, кто в ней заинтересован

Для собственных объектов в «классическом» наследовании то же самое можно сделать с помощью интерфейсов, и даже больше — явная реализация интерфейса позволяет объекту иметь даже несколько методов с одинаковым названием, и они не будут пересекаться. Символы же всё равно упираются в строки, и точно так же можно получить коллизии, потому что Symbol.for("a") === Symbol.for("a").

Для чужих же объектов такое вообще лучше не делать, потому что прототипы глобальны и изменение может иметь непредвиденные последствия в других модулях. Именно по этой причине prototype.js так быстро попал в ранг антипаттернов.
Символы же всё равно упираются в строки

Они не обязаны в них упираться. Вы можете сделать так (делая отсылку к моему предыдущему примеру):


mycoollib.ToString = Symbol ()

...

Boolean.prototype[mycoollib.ToString] = function () { ... }

И никаких коллизий.

>Умные дяди выяснили, что статическая типизация позволяет повысить качество приложений и сократить время разработки
Это, мягко говоря, неправда. Например, вот.

>Вместо этого
>Вместо этого
>Вместо этого
>Вместо
Парадокс ситуации в том, что вы по какой-то причине считаете, что есть только один правильный путь, в то время как это не так.

>Например, как сделать словарь, ключи которого являются объектами?
Map же.

>Увы, никак — есть WeakMap, но он работает немного по-другому.
А вы думали, что наличие «Weak» в слове «WeakMap» имеет какое-то отношение к «получению слабых ссылок»? Ведь есть же спецификация, ну.

>будет новый класс Proxy
И это нормально. Когда-то и в C# такой возможности не было — сами же это говорите. То, что сейчас происходит с JS — это восхитительно. Буквально на наших глазах язык превращается из сугубо нишевого в, так сказать, настоящий. Взрослеет, растет. Особенности его применения (многочисленные вендоры браузеров, в частности) этот рост затрудняют, и это понятно. Но растет же!

>по-прежнему масса возможностей написать код так, чтобы сломать оптимизации.
Это только в JS так?

Если позволите, я и на другой комментарий отвечу.
>хорошо в теории, плохо на практике
Почему? Кстати, вы почему-то в этом комментарии раз 5 упоминаете компиляцию. Какое она имеет отношение к JS?

> творить грязные трюки
Почему вы считаете это грязными трюками? Вот это прям особенно интересно.

>Symbol.for(«a») === Symbol.for(«a»).
Это касается только символов в глобальном реестре.
Это, мягко говоря, неправда.

Соглашусь, это спорный момент. Мнения на этот счет есть разные. Однако я еще не видел, чтобы на динамически типизированных языках писали приложения, к которым предъявляются особые требования к надёжности (банковское ПО, бортовые компьютеры, и т.д.)

есть только один правильный путь, в то время как это не так.

Уже описал в предыдущем комментарии. Прототипное наследование требует либо жирной прослойки в рантайме, либо безумно сложной реализации VM. Как следствие, языков с прототипным наследованием гораздо меньше, чем с «классическим» — кроме EcmaScript, Lua и LISP я других толком не знаю.

Это только в JS так?

Статически типизированный язык имеет больше ограничений, поэтому больше гарантий. На основании них можно выполнять массу оптимизаций, недоступных динамически типизированным языкам. Запутать компилятор можно в любом случае, но для этого потребуется сильно больше кода и есть шанс, что программист подумает — «как-то слишком сложно получается, возможно я делаю что-то не так?».

Кстати, вы почему-то в этом комментарии раз 5 упоминаете компиляцию. Какое она имеет отношение к JS?

JIT.

Почему вы считаете это грязными трюками?

Расширять прототипы встроенных объектов опасно по причине возможных конфликтов. Методы-расширения решают проблему, но в JS их невозможно реализовать по причине динамической типизации. Что же касается подмены прототипа, то тут сам Брендан Эйк признается, что идея была отстойная.

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

Это касается только символов в глобальном реестре.

Виноват. Действительно, это верно только для символов, полученных через Symbol.for. Но тогда становится еще страннее: если Symbol придуман как раз для того, чтобы к данным мог получить доступ только тот, для кого они предназначены, зачем сразу же закладывать дыру в абстракции, создавая глобальный реестр символов и Object.getOwnPropertySymbols?

Object.getOwnPropertySymbols нужен, чтобы можно было склонировать объект. Например если вы миксины делаете, без этого никак. Или для отладки, чтобы например в консоли было видно, че там за символы у объекта. Дырой было бы, если бы эту информацию нельзя было бы получить — это как раз разрушило бы консистентность.


данным мог получить доступ только тот, для кого они предназначены

Это так и есть. Ведь если у вас нет ссылки на символ (и он безымянный, не через реестр), то вы не можете никакой осмысленный доступ к свойству такому получить. Это как квантовая информация, она вроде бы есть, а вроде бы и нет. Но её можно скопировать, вот за этим и нужно.

Вы из тех, кто не осилил прототипы и замыкания?

Вы из тех, кто не осилил строгую типизацию?

(а что, собственно, нужно «осиливать» в прототипах и замыканиях?)

Ну да, в 2003, когда json, xhr и инлайн-блоки умели не все браузеры, трэша в js не было.


Был конечно, как его могло не быть в языке, который написан за полтора дня на коленке?

Да не в этом дело, платформ разных сравнительно много и договориться сложно (особенно когда договариваться не хотят). Даже в одной компании это уже проблема, а тут… Язык как язык, проблема не в языке, а в способе его развития. Я уверен, был бы вместо js — python, было бы так же: у кого-то второй, у кого-то третий, у кого-то второй но кастрированный, и стандартная библиотека "почти совместимая но есть нюанс".

Вот не уверен я, честно говоря. В языке программирования должна быть стройность и логичность, «внутренняя красота», если можно так сказать. Начиная использовать какую-то новую функциональность языка, в хорошем языке интуитивно понимаешь, что тебя ждёт: как примерно реализован интерфейс, какие методы потокобезопасны, какие нет, как будет проходить обработка ошибок и т.д.
В javascript этого нет и никогда не было. Те же == и ===, null и undefined, родовая травма в виде isNan. Чтобы на нём писать, его надо заучивать, реально. Нужно помнить, что при == будет приведение типов, а при === не будет. Нужно помнить, что в объекте error есть свойство message, которое хранит сообщение об ошибке. Нужно помнить, что проверять есть ли свойство нужно через if(foo.bar), потому что сравнения с null или undefined будет недостаточно. На том же хабре полно статей о подводных камнях js.
Минус вам, слишком много хотите от мира.

Я немного не о том. Да, язык странный, но почему он такой? Потому что его нельзя нормально развивать: вот предлагаете вы фичу, гугл говорит "пшёл нафиг, у нас свой язык", ms говорит то же самое гуглу, apple тоже пилит что-то своё. Договориться в условиях жёсткой конкуренции не поулчится, поэтому мы имеем такой странный язык.
2016 год. Вендоры собрались и поняли, что договориться и развить общий язык не получится в принципе, подход "вшивать язык в бразуер" для больших приложений не работает, разработчики почему-то в экосистему пользователей загонять не хотят, а начинают писать транспайлеры, чтобы оно работало везде и у всех, хотя это и не так удобно разрабатывать.
Поэтому решили сделать webassembly (и houindi), который теоретически должен решить проблемы языка в рантайме, и это на самом деле очень круто. На чём хочешь, на том и пиши, только скомпилируй вот в этот формат. Кто первый сделает юзабельный фреймворк, работающий одинаково хорошо в браузерах и десктопе, получит конфетку. Когда это будет — интересный вопрос, наверное даже не в 2017.

Скорее всего и здесь не договорятся. В итоге получится пачка принципиально разных реализаций байт-кода.
А сервер, предварительно определив user-agent, должен будет выдавать откомпилированную сборку сайта под конкретный браузер.

Ну, из того что есть сейчас — формат байт-кода стандартизован, спека есть, все (!) вендоры в процессе имплементации, пока хорошо.

> if(foo.bar)
Нет, так нельзя проверять, есть ли свойство. Сдается мне, что не работаете вы с JS с 2003 года.
НЛО прилетело и опубликовало эту надпись здесь
Date это полный ппц.
У меня API все на питоне написано, datetime.date по стандарту как «yyyy-mm-dd» передается, приходится каждый раз на входе в ангуляр парсить строку, а, потом, на выходе собирать. Ненавижу JS.
по стандарту как «yyyy-mm-dd» передается, приходится каждый раз на входе в ангуляр парсить строку, а, потом, на выходе собирать. Ненавижу JS.
Вы сами конвертируете в строку, а потом жалуетесь, что приходится парсить. Передавайте/получайте сразу дату, и при чем здесь JS?
НЛО прилетело и опубликовало эту надпись здесь
неадекватен по API, по моему мнению, — Date

Эта проблема встречается в большинстве языков, к сожалению. Работа с датой и временем — сложная штука. В некоторых случаях народ успел оглянуться и посмотреть на следы от грабель на телах конкурентов ,)

1. Следует помнить только то, что примитивный объект в java не может быть null.
2. Void — объект-обертка над void, так же, как и Integer над int.
3. см. п.1. и тогда всё логично.

Void — это тип, его нельзя инстанцировать в отличии от Integer и компании. Значению типа Void можно присвоить только null, что вполне логично.

А с isNaN-то что не так? :)
НЛО прилетело и опубликовало эту надпись здесь

стесняюсь спросить — а что должно быть? false?

НЛО прилетело и опубликовало эту надпись здесь

Вы точно понимаете что значит NaN?

А вообще есть конечно там некая толика всеобщего JS-раздолбайства, человек просто пример неудачный привел.


isNaN(NaN); // true - ок
isNaN(1); //false - ок
isNaN(undefined); // true - ну... допустим ок
isNaN("foobar"); // true - ок
isNaN("1"); // false - ... эээ
isNaN(false); // false - ... нуу
isNaN(null); // false - пожалуй с меня хватит.

Я думаю хорошо было бы если бы оно в действительности только на NaN true возвращало, что и пытался донести staticlab

НЛО прилетело и опубликовало эту надпись здесь
когда человек, пришедший из других языков видит, что в javascript'e называется словом this, его волосы неизменно начинают шевелиться
И что же в JavaScript называется словом this отчего начинают шевелиться волосы?
какая-то хрень в нем называется этим словом. Самые близкое по смыслу наименования, которое приходит на ум мне, это, наверное caller или invoker или context, хотя и они тоже плохие. Ну уж хотя бы нет коннотаций с Java-шным this'ом.

Ну вот куда это годится?

var MyObj = function () {
    this.fn = function () {console.log(this)};
}
a = new MyObj();
a.fn();
// MyObj
var b = a.fn;
b();
// Window 


Ну это документированное и ожидаемое поведение языка. Хотя вы правы — понятие «Контекст вызова» здесь больше подходит, нежели «Указатель на объект» или что-то в этом роде.

‘Sometimes when I'm writing Javascript I want to throw up my hands and say "this is bullshit!" but I can never remember what "this" refers to.’
— Ben Halpern ‏@bendhalpern 20 Mar 2015

Кормлюсь js c 2006, и то, что сейчас происходит, в последние лет 5 — во многом лютый офигенчик.


Что у нас было тогда? Prototype c весьма странной идеей и расплывчатой ответственностью. Примерно такой же Motools. jQuery, чей подход мне не нравился вообще никогда, с его бесконечными отвратительными плагинами. Потом появился переусложненный ExtJS, императивный на всю голову qooxdoo и прочие странные порождения сумрачного корпоративного гения. Единственный приличный был y5, который умер, где и родился — в недрах яндекса. Backbone, при всех его недостатках, был лучом света в темном царстве.


Бандлер/минификатор был либо родом из серверного фреймворка (везде со своими идиосинкразиями), либо самописный (которые моя бабушка описала бы как «мальчик-то он хороший, только дрищется»). Все они писались серверными программистами без малейшего понятия, что же все-таки нужно фронтендеру. RequireJS, опять таки при всех своих недостатках, опять же был лучом света и т.д.


Сборка происходила в лучшем случае Makefile-ом. Это, конечно, довольно универсальная система, но на винде из коробки ее нет. grunt/gulp/webpack более кроссплатформенные решения в этом смысле, плюс не надо переключаться с JS на чей-то эзотерический синтаксис.


Про юнит-тесты я вообще молчу. Да, был, например, QUnit, но в отсутствие нормальной модульной системы и ее поддержки, пользоваться им было довольно грустно.


В общем, сейчас в 99% случаев можно найти «точное такое же, но с перламутровыми пуговицами». И да, никто не запрещает и сейчас писать так же, как в 2003 — все в одном-двух файлах, без сжатия и склейки, без сторонних библиотек. Просто сейчас мы делаем гораздо более сложные вещи, которые в двух файлах уже не уместить (оставим неуместное использование тяжелых фреймворков на простеньких страничках на совести тех, кто так делает).

Это палка о двух концах, имхо. Тогда не было технологий и альтернатив и да, приходилось пользоваться кривым Prototype и тратить кучу времени на то, что сейчас можно сделать за час (та же сборка проекта).
С другой стороны, тогда и порог вхождения был гораздо ниже, изучаешь синтаксис языка, читаешь документацию к Prototype и вперёд фигачить.
То что происходит сейчас замечательно описано в статье, её показать человеку, который только входит во фронтэнд, он с высокими шансами станет как бабушкин мальчик. Делается то всё просто, если знаешь как, а чтобы во вё разобраться надо немеряно времени потратить. Т.е. порог вхождения вырос на порядок как минимум.

Ну это понятно:) Но ведь и сложность задач возросла. Если надо склепать какой-нить лендинг-пейдж/визитку или там галерейку для сайта на вордпрессе — можно все так же, window.onload = function() {} и вперед, и это нормально. Я бы «удивился», если кто-то предложил использовать react + babel для этого, все либы будут весить гораздо больше пользовательского кода, а выигрыш минимален. Я же говорю, никто не запрещает сейчас делать так же, как и тогда — только если вы попробуете те подходы на сложном приложении, вам будет грустно.


Сейчас везде так. Видели оригинал? Или вот покажи мне сейчас кто-нибудь стэк для написания десктопных приложений, я буду таким же мальчиком. Подозреваю, если бы братьям Райт показали «Конкорд», они бы тоже сказали: «ну да, круто, но у нас вот из говна и палок можно за час собрать, и летает». Сравните телефоны сейчас и во времена Белла. Да, сейчас все сложнее, зато и воможностей больше. А звонить-то можно и по-прежнему.

Я могу сказать рамках .net, котором пишу. Там такого нет. Есть основная технология, WPF (Windows Presentation Foundation), которая использует паттерн MVVM. Первая версия вышла 2006 году, в дальнейшем вносились косметические изменения. Она позволяет использовать весь функционал .net Framework. Есть библиотеки дополнительных контролов, выпускаемых различными вендорами, типа Telerik, но их использование опционально.
Фактически, все новые приложения на платформах MS (Windows 10, Windows.Store, Windows.Phone, Silverlight) пишутся на WPF, который стандартизирован.
При этом новые технологии, появляющиеся в рамках .net framework (async/await, EntityFramework) вплетаются в WPF без нарушения обратной совместимости.

Спасибо. А UWP сюда каким боком относится? Я слышал, что можно что-то там делать на JS, можно ли сделать live tile и как? Пригодится ли мне WinJS или это сугубо набор контролов? Я знаю, что есть кросс-платформенное Mono и что оно в какой-то мере отстает от мейнстримного .net, оно умеет в WPF?

НЛО прилетело и опубликовало эту надпись здесь

Я не только из риторических целей спрашиваю, мне правда хочется сделать кое-какое приложение в виде живой плитки.

Я, честно говоря, не изучал его глубоко, не приходилось сталкиваться. Но предполагаю что там идеология похожая.
Есть ещё Apache Cordova, там можно, насколько я понимаю на JS писать.
Но опять же, у .net идеология, что всё компилируется в байт-код MSIL (а-ля ассемблер), который затем, во время исполнения, компилируется в нативный код, специфичный для платформа. Скорее всего, там просто сделан компилятор, который превращает JS в MSIL (байт-код).
Есть ещё Apache Cordova, там можно, насколько я понимаю на JS писать.

Это просто обертка над WebView (точнее, генератор таких оберток под каждую нужную платформу). В WebView показывается ваша страничка (оффлайн, она лежит в ресурсах приложения). Обертка обеспечивает проброс нативных API платформы.


Расскажите мне лучше то, чего я не знаю.

Я, честно говоря, не изучал его глубоко, не приходилось сталкиваться.

Ну вот видите. Вы пишете на .net и не можете мне про него рассказать. А у JS, видите ли, сложный и запутанный стэк.

Я могу вам рассказать про .net, я не изучал глубоко UWP приложения, так как не было пока проектов, связанных с ним.
.net же огромная платформа, которая делится на множество направлений.
Изначально были Windows.Forms, Asp.Net Web Forms, .net CE, .net embedded. Потом появились WPF, WCF, WWF, ASP.NET MVC. Windows CE канул в Лету и на смену ему пришёл .net под Windows Phone, сейчас активно развивается UWP (в рамках мобильных платформ) и Asp.Net Web API (в рамках веба), выделившийся из ASP.NET MVC. Сейчас активно .net Core развивается. Из этого списка я вообще не трогал UWP, .net Embedded и чуть-чуть трогал .net Core. Про остальное спрашивайте, расскажу.
НЛО прилетело и опубликовало эту надпись здесь
Например эти
Интересный стек технологий сейчас используется в Web разработке.
У нас в компании похожий стек, только про Hadoope
Поскорее бы уже монополия инструментов от Гугла.
Программирую уже 18 лет, из них 11 лет для WEB. Прочитал статью, понял что я почти ничего не знаю. Пора перестать быть самоучкой — велосипедостроителем, и начать изучать готовые велосипеды. И уже на них ездить…
Вот. В этом истинная (полезная!) цель данного поста. Можно использовать как глоссарий терминов, о которых за несколько дней (хотя бы) почитать, посмотреть примеры и т.д.

Потом осознать, что потратил месяц, просто чтобы начать понимать, что значат все эти термины. Прикинуть, что на освоение позволяющее использовать все это в реальной работе уйдет от года(а за это время появится еще много чего). Ну и плюнуть на все это и за выходные освоить Dart. За вторые выходные написать то самое TodoMVC которое просто будет работать.

История о том, что кто-то не может выбрать набор инструментов соразмерно задаче. История была актуальна во все времена.
ага, любят в нашей отрасли сколачивать скворечники, используя инструмент для проектирования авианосцев
Позвольте с Вами не согласиться. Часто начинается как скворечник, а заканчивается как Боинг. Та жа попсовая Java даёт инструменты, чтобы одинаково эффективно строить и скворечники и загоны для крупного рогатого скота.
Чаще нужен именно скворечник. Разрабатывается он как авианосец и на выходе получается чёрти что за баснословные деньги и неприемлемые сроки.
А те редкие скворечники, которым посчастливилось показать потенциал авианосца, можно и переписать с нуля.
И, кстати, вообще вся история js, экосистемы js, сообщества js как бы показывает нам очередной фильм-антиутопию про далёкое будущее. Когда на ИТ-планету упал кусок рыночного капитала, образовался неизвестной природы js-копролит чёрный и блесятщий.

И началось постепенное разделение ИТ-людишек на два класса — кровожадная элита, которая делает какой-либо рантайм js (неважно, браузер, нода, embed-версию) и всех остальных, которым дали js и песочницу, а постоянное нахождение в ней эволюционно отупляет даже самых способных голодранцев.

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

И то же самое относится к исполнителям, то есть огромной толпе буллшит-кодеров, которым просто надо жить и кушать, и плевать, что своими копытцами поддерживаешь огромный чёрный js-копролит, возвысившийся над планетой.

И все, вообще все понимают, насколько js унылое дерьмо, но целая планета трудится над этим дерьмом, затыкая носы ради великого доллара на вершине js-копролита.
— Эй, я бы хотел научиться писать крутые веб-приложения. Слышал, у тебя есть опыт.
— Да, я как раз занимаюсь фронтендом, юзаю пару тулз.
— Круто. Я щас делаю простое приложение — обычный TODO-лист, используя HTML, CSS и JavaScript, и планирую заюзать JQuery. Это норм?
— Не-не-не. Для обычного TODO-листа слишком много оверхеда. Пишешь софт на любом удобном языке, подрубаешься через telnet и юзаешь. Если хочешь секурности — используй ssh.
Слишком много оверхеда. Просто возьми бумагу и карандаш.
Бумага и карандаш — ненужные костыли. Лучше просто не забывать, что хотел сделать.
Не забывать — лишний расход памяти. Лучше просто не хотеть делать.

Лучше тогда вообще… постойте, это уже какая-то пропаганда самоубийств получается. Я слышал, это незаконно теперь!

Странно, что современный фронтенд — это еще законно.
Пропаганда, если не самоубийств, то, как минимум, наркотиков.
Читая комментарии в очередной раз подчеркнул для себя — JavaScript не оставляет равнодушным никого. Одни яростно ненавидят его, другие обожают. Видимо именно так и должно реагировать сообщество на самый популярный и в то же время противоречивый язык программирования современности. Самое время запасаться попкорном.
Когда надо не трепать языком, а работать за деньги с обязательствами перед клиентами и начальством вся эта заднеприводная противоречивость встаёт на пути нормального размеренного трудового процесса. Но, опять же, власть копролита сильнее голоса разума.
Это IMHO не JavaScript. Это экосистема технологий и приемов, складывающаяся вокруг JavaScript волей случая (в данном посте — даже вокруг фронтенд-разработки).
На backend'е ситуация ещё хуже. Фронтенд хотя бы ограничен одним языком (js), тогда как backend — это целая пачка языков программирования, вокруг каждого из которых громоздится целая гора фреймворков.
При том, что выбор языков носит исключительно косметический характер (в стиле «мне не нравится синтаксис»), т.к. возможности сходны, и вряд ли можно найти такую задачу, которую легко решить к примеру на Python+Django, но невозможно на PHP.
Я равнодушен лет так 20. Это просто инструмент, который использую, когда считаю что лучше использовать его, а не альтернативы.
Проблема в том, что альтернатив-то, по сути, нет. Ненавидите джаву — пишите на шарпе (благо, уже кроссплатформенный), ненавидите ооп — пишите функционально, ненавидите жс — ууупс…
Да, есть дарт, есть тайп/кофе/*скрипты и на некоторых из них даже почти удобно писать, но это всё просто запихивание того же самого под ковёр. Не видно, но всё равно попахивает.

И да, я понимаю, почему альтернатив нет — браузеров много, и пропихнуть эту самую альтернативу почти нереально, но ситуация от этого менее плачевной не становится.

Недостаточно трэша. Теперь мы хотим в качестве бэкенда использовать не какую-нибудь ноду, а ASP.NET (не Core) с бандлами. Когда для сборки React, минификации, трансляции less используются не обычные front-end инструменты, а куча разных пакетов вроде DotLess, ReactJS.NET. В Core куда удобнее, имхо — bower, grunt и прочее веселье.

Я один не понимаю, зачем для подобных действий использовать средства фреймворка (например, ассеты в RoR) вместо использования Gulp/Grunt/Bower/Webpack?
Очень трудно понять, для чего нужны вот такие вещи сегодня.

Я тоже не понимаю этого. Примерно так: ты новичок, изучаешь новую технологию, читаешь гайды, а там показан такой путь и сказано, что это труЪ и кошерно.


Хотя у бандлов в асп.нет есть преимущество перед конкретно Gulp\Grunt — с помощью их и web essentials можно на лету пересобирать. Сохранил css\less, и у тебя сразу изменения в браузере, а не подождал, пока watch grunt'а увидел, пересобрал и потом обновляешь страницу.


Но такую магию вроде позволяет WebPack. Я тоже за родные для фронтенда инструменты.

Ну уж ivereload для стилей и grunt умел (точнее, grunt-livereload).

У меня gulp пересобирает scss без перезагрузки страницы вот так:
— в таске styles появляется строка .pipe($.if(browserSync.active, browserSync.stream({match: '**/*.css'})));
— в таске browsersync остается gulp.watch, но без вызова bs.reload()
Потому что они есть из коробки, хорошо изучены и работают. Зачем отказываться от них и вводить в проект новые сущности?
То чувство, когда освоил angular, а он умер и теперь боишься учить новую технологию, понимая что через год-два ее ждет та же участь
Если степень фрагментации технологий продолжит возрастать теми же темпами, то ценность знаний конкретных технологий рано или поздно станет равной нулю. И хорошим программистом будет считаться человек, способный за два дня освоить конкретный набор технологий, которые он увидел впервые, быстро создать на этих технологиях проект, после чего очистить мозг от выученного, т.к. пока проект создавался, данные технологии вышли из употребления и больше никогда не понадобятся.
На моём опыте, ваша фраза «И хорошим программистом будет считаться человек, способный за два дня освоить конкретный набор технологий» актуальная уже сейчас. С начала прошлого года мне довелось поработать над тремя frontend проектами с абсолютно разным набором технологии, начинаю со сборщика и фреймворка, заканчивая набором библиотек и плагинов, даже стиль написания кода приходилось соблюдать разный. И только за счёт способности к быстрому обучению и адаптации удалось в этом преуспеть, а не сойти с ума.
блин, уже умер???
> И хорошим программистом будет считаться человек, способный за два дня освоить конкретный набор технологий

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

Ну, глядя на тенденцию обучения программированию с младых ногтей, думаю что это не будет проблемой в ближайшем будущем

Шутки шутками, а я бы с большим удовольствием прочитал подобный пост про упомянутый деплоинг. Крайне удачная подача материала дабы быстро освоиться в теме и терминологии. Год назад подобный пост сохранил бы мне неделю времени потраченную на гуглинг.
Вы хотя-бы список технологий приведите, чтобы понять, что подразумевается под делоингом веб-сайтов
Этот пост как раз и хорош тем, что перечисляет список технологий и даёт им краткое описание, рассказывает в каком месте их можно применить.
Что-же, если стоит задача написать todo-list — возможно тут и jquery лишний, браузерные api уже не те что раньше.
Но обычно стоит задача написать реально сложное web-приложение, и вот тут все эти технологии уместны и нужны. То что их много, они сложные, и постоянно меняются — безусловно вводит в ярость человека, который привык к тому, что может написать пару сток на js в перерывах между своим .net mvc или типа того, и считать себя full-stack. Я бы посоветовал таким людям смирится, и просто сосредоточится на своей технологии, а front-end оставить тем, кого все эти слова не смущают.
Ой, еще никто не написал, что flux — прошлый век, и крутые перцы используют redux xD
Еще и relay с graphql на подходе.
Крутые перцы уже используют mobx

Это шаг назад по сравнению с redux, потому что теряется predictability. Выглядит мощно да, но и goto в C выглядел мощно. А потом все поняли, что это верный способ себе ногу отстрелить.

goto в си используется довольно часто для освобождения ресурсов в конце функции

Ага, как и setjmp и longjmp. Только эти вещи используются в очень частных случаях, и только когда это реально оправдано. Observables это реально интересная вещь — ложится на наши естественные ментальные модели хорошо. Как и гото, например. Он ведь тоже когда-то появился, потому что это для нашего мышления естественная штука. Проблема в том, что наши ментальные модели зачастую говно. Человеку свойственно ошибаться и нести чушь.


То есть, иногда встает выбор — либо учить что-то новое и прорывное (новую ментальную модель) — что дает принципиально новые возможности (как функциональный подход и redux) — либо заниматься луддизмом, и цепляться за mutable state, просто потому что мы уже привыкли так мыслить, а новые парадигмы мы в голове помещать не хотим. Но время все расставляет по местам, думаю что штуки типа mobx для менеджмента состояний будут оправданы только в маленьких простых приложениях, а в больших и сложных это будет шаг назад в сравнении с Redux. Это чем-то похоже на дилемму из статьи, кстати (jquery vs react).

> как и setjmp и longjmp
Они как-раз специфичные. А goto — нормальная, довольно распространенная практика в Си

> либо заниматься луддизмом, и цепляться за mutable state
mutable state отличная, рабочая парадигма. Идеологи реакта прославляют иммутабельность потомучто она критична для работы реакта — это его прямое ограничение. Как только кто-то сделает «реакт без принудтельного stateless и виртуального DOMа» все забудут этот недохаскель как страшный сон.

В чистом C возможно. Но в C++ это не так. Я писал на C++ много лет (3D графика), и мне ни разу не пришлось использовать goto. Хотя он там есть. Я именно об этом и говорю — наличие инструмента не делает его использование оправданным.


Так же и мутабельность — это только выглядит «удобным», как гото когда-то выглядел удобным, пока не появились лучшие инструменты. И точно так же находились те, кто считал, что старый подход лучше, потому что «удобнее». Вы думаете мало было холиваров насчет гото? Вот и mutable state ждет такая же судьба. Останется уделом низкоуровневых вещей каких-то, где без этого вообще нельзя. А на макроуровне это забудут, как страшный сон.


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

В плюсах для освобождения ресурсов используют деструкторы. Но даже на плюсах вы использовали goto. Switch-case не более чем легкий синтаксический сахар над goto

> не понимая до конца преимуществ иммутабельности в макромасштабе
Расскажите о преимуществах иммутабельности в макромасштабе, будте так добры

Так же можно сказать что и immutable state это легкий сахар над mutable state, ведь архитектура компов это Тьюринг-машина. Я не очень понимаю такую «логику» рассуждений. Про преимущества есть в статье.

Switch-case строже, чем goto.

А так-то всё — синтаксический сахар поверх машинных кодов, но это же не повод.

Расскажите о преимуществах иммутабельности в макромасштабе, будте так добры

Когда у вас вся логика спрятана в immutable-функции, то становится очень легко и просто рассуждать о коде (as in «reason about the code»).
Вот и mutable state ждет такая же судьба.
Останется уделом низкоуровневых вещей каких-то, где без этого вообще нельзя.
А на макроуровне это забудут, как страшный сон.

Пруфлинк бы. А то каждый месяц кто-нибудь не слишком хорошо знакомый с историей развития языков открывает для себя immutable state и предрекает немедленную кончину объектов с изменяемым состоянием, а они все, гады такие, не помирают и не помирают никак.


А не помирают они потому, что есть задачи, которые хорошо решать в парадигме чистых вычислений, а есть задачи, которые естественнее и удобнее решать в рамках ООП. Например, складской учет, оперирующий ящиками и коробками, можно, конечно, решить без изменяемых объектов — но количество костылей, которые придется нагородить вокруг, заставит глаза кровоточить гораздо раньше, чем первый пререлиз увидит свет.


Нет серебряной пули: вот единственно верный ответ на этот вопрос. Есть масса задач, в которых давно отправленный на пенсию Backbone даст сто очков форы любому новомодному redux’у. Поэтому фанатиков технологий и недолюбливают в любом мало-мальском энтерпрайзе.

https://habrahabr.ru/post/308154/


На высокоуровневых задачах в вебе про mutable state уже забыли. Я в прошлом году писал WYSIWYG редактор который работал с изменяемым состоянием, хранящимся напрямую в DOM. Было очень сложно добиться безглючности и понятности кода, а также работы штук типа стека undo/redo. Сейчас я смотрю на последние разработки редакторов типа Slate или Draft.js — это невероятно, насколько иммутабельность помогла им выстроить хорошую архитектуру, позволяющую в разы больше, чем возможно было до того.

Я вам говорю: «разные задачи — разные инструменты, например, забивать гвозди удобнее молотком, а закручивать шурупы — отверткой».


Вы мне в ответ: «я и еще три крутых пацана вчера забивали гвозди, ничего круче молотка нет, вообще все все все уже давно отказались от отверток».


Ну ок. Пруфлинк засчитан.

Так вы посмотрите с чего ветка-то началась, пример goto не просто так был приведён. Каждая новая технология не отменяет старой, но расширяет горизонт возможностей, а старая технология остается в рамках этого расширенного горизонта маленькой нишей. Сегодня люди до сих пор используют и C++, и ассемблер даже — но на прикладном уровне этого уже нет давно. Вот так же и mutable state — это старая парадигма, которая не способна решать «бытовые» задачи, с которыми люди сталкиваются сегодня. Просто это новые задачи, новые вызовы. В рамках которых люди действительно уже отказались от «отверток». А отвертки остались в своей области применимости.

Во-первых, immutable states и чистые функции примерно настолько же «новая» парадигма, насколько и goto.


Во-вторых, mutable states живее всех живых во многих прикладных задачах. То, что вы почему-либо с таким классом задач не сталкивались, означает только то, что ваши задачи удобнее решать с неизменяемыми объектами. Вы пока не привели ни единого аргумента, почему бы это было так, кроме «мамой клянус», «сам писал целый год целый проект» и «совершенно очевидно». Это все детский сад.


Вот вам простой пример: я у себя в блоге накладываю на фотографии информацию о месте съемки, которую вытаскиваю сырой из EXIF и хожу из клиента в nominatim, который отвечает не всегда, поэтому я успокаиваюсь после двух отлупов. Предложите мне вариант проще, чем хранить «по этой фотографии опрос окончен» в самом объекте и рисовать общую карту с маркерами по факту «все объекты успокоились» — и я уверую.

Задача которую вы описываете — это не высокоуровневая задача, это как раз область применимости отверток.


> То, что вы почему-либо с таким классом задач не сталкивались


С чего это я не сталкивался? Я с таких задач и начинал, можете резюме глянуть. В детстве 3D движки писал (DX/GL), там таких задач как раз полно. Это все лоу левел.


Я вам привел совершенно конкретный пример весьма сложной высокоуровневой задачи (WYSIWYG редактор), где immutable state упрощает код на порядок, делая его предсказуемым, высокопроизводительным и легко расширяемым: https://github.com/ianstormtaylor/slate#principles


А вы мне про какие-то EXIF из фоток. Детский сад...

Вот так же и mutable state — это старая парадигма, которая не способна решать «бытовые» задачи, с которыми люди сталкиваются сегодня.

По-моему, это ваши слова, поправьте, если ошибаюсь. Теперь на сцене появляются какие-то «высокоуровневые» задачи. Ну ок, визивиг, «immutable state упрощает». И что из этого следует, кроме того, что есть пример задачи, где неизменяемое состояние — благо? С этим тезисом даже самые отъявленные оописты не спорят. Вот только он ничего не доказывает.


Если бы вы с самого начала использовали слово «некоторые» вместо «все» (даже «большинство» можно было бы стерпеть) — я бы вообще не встрял. Каждый волен восторгаться новыми религиями, хоть каждый год.


Напоминаю еще раз важный момент, который вы в ответах успешно игнорируете: immutable state — ровесник goto. У него было время убить вокруг вообще все живое. Но этого не случилось. Потому что не для всех задач это благо. Вот и все.


Рано или поздно ваша высокоуровневая задача захочет восстанавливаться из локалстораджа при переоткрытии браузера (ну, если она для людей, конечно, а не для демонстрации высокоуровневости). И voilà.

Вы напрасно сравниваете гото и иммутабельность, в плане их «старины», пытаясь из этого какие-то выводы сделать. Гото это чисто инженерное решение, которое было обусловлено низкоуровневой архитектурой вычислительного железа. Оно старое просто потому что компы старые.


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


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


Вы просто путаете теплое с мягким.

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

Ох. Джо Армстронг уже и так икает в безмолвном изумлении.

Я кстати уверен что в будущем люди не то что «забудут недохаскель». Но реально перейдут на хаскель. Ну точнее его браузерную инкарнацию какую-нибудь, типа Elm. Очевидно же, что все к тому идет, просто не революционным, а эволюционным путем. JS все больше и больше становится похож на это, в какой-то момент уже просто не будет смысла использовать JS, все свитчнутся на какой-нибудь транспилируемый в него язык. Они и сейчас есть, такие языки, просто люди еще не понимают до конца, зачем они нужны — но это в какой-то момент станет очевидно всем. И появление таких вещей как React/Redux в массовом сознании это очень мощные сигналы к этому.

> JS все больше и больше становится похож на это
Не было в JS ничего подобного до прихода реакта. В нем, насколько я понимаю, иммутабельность нужна чтобы реакту быстро найти изменения. То есть для того чтобы его внутренности правильно отработали. Разработчику-пользователю фреймворка она ничего кроме чувства собственной важности не дает. Поправьте, если я ошибаюсь

Пользователю фреймворка это дает React, лол. Он был бы невозможен без этого. Я именно об этом и говорю, это не просто «быстро найти изменения», это и есть ключевой момент во всем этом. В макро масштабе.


И тут интересный дальше момент — это определяет архитектуру нашего приложения. То есть, выгодно юзать Redux. А это уже все прямиком пришло их функциональных языков, из Elm в частности. И постепенно никакого смысла в том чтобы использовать JS вместо Elm не будет. Потому что Elm позволяет еще и статически верифицировать всю программу так, что у вас вообще нет runtime exceptions. А это и есть ультимативная цель всего этого замеса.

Не совсем так, Реакт может работать и с изменяемым состоянием.

Мне одному кажется, что мы все сейчас наблюдаем пузырь, сравнимый с доткомовским?
Все эти недавно бывшие кодерами на похапе или полгода верставшие лендинги люди раздувают ценность знаний новых технологий, и их реально нанимают работать на хорошие должности. А на деле эти люди освоили пару алгоритмов или парочку фреймворков типа Angular2 и иже с ними.
Все больше кажется, что охотнее нанимают не спецов, пусть и в драных кедах, а людей, умеющих себя подороже продать, освоивших что-то интересное, но не знающих даже основ.
Backend-илита подтянулась, ну наконец-то.
Я пока, по рейтингу. — в самом низу — похапешник)
Как должно быть заметно по моему первому комментарию, я не считаю себя элитой и всячески не одобряю похожего мнения от любого человека.
Всегда и во всех областях охотнее нанимают тех, кто умеет продать себя :)
Отовсюду слышно, что с радостью нанимают «молодых и перспективных» разработчиков, у которых горит в глазах огонь при виде новейших технологий. Люди поопытнее уже прошли эти круги ада новых и модных технологий как минимум пару раз, и подход у них более практический.
Имхо, разумеется.
Я бы еще добавил:

— А как в этот Webpack'e подключить стили?
— Ну тут все просто, ставишь precss, postcss-loader, postcss-import, css-loader, style-loader, file-loader, normalizr, normalizr.css, autoprefixer
— Поставил все как вы сказали, но картинки не загружаются.
— Очевидно вы забыли установить image-webpack-loader

Перечитал статью — так и не понял над чем смеяться? С указанным стеком познакомился за месяц, за два-три месяца активной работы втянулся до уровня заглядывать в доки не больше пяти раз за день, второй год успешно на этом зарабатываю. То есть если даже оно все разом сейчас умрет — я считаю что свои инвестиции времени я отбил. Что не так?  Где можно прийти с улицы и начать грести лопатой? При чем здесь кривизна языка разработанного на коленке? Современный js от того языка довольно далеко ушел. В каком языке достаточно знать только язык что бы продуктивно работать? Java? С++? (программируем сфероиды в вакууме, ага)  Почему webpack — костыль, а make никсов — произведение исскуства? npm чем то хуже (или лучше) других менеджеров пакетов? Мужики, в любой нише придется изучать инфраструктуру, не потянули js — не расстраивайтесь. Да, сейчас порог вхождения для джисера гораздо выше чем было раньше. И уровень проектов — выше. И js давно вышел из песочницы броузера. Но это не повод расстраиваться — есть масса других ниш, другие стеки, возможно стоит начать с них )

make не произведение искусства, make — стандартный инструмент. И будет стандартным и через 5, и через 10 лет.

Я зарабатываю на жизнь написанием кода на C++ (в основном). Я знаю C++, и всё. Ну, и часть библиотек из Boost ещё знаю немножечко — часто использовать приходится. Из системы сборки — cmake (который, кстати, в том числе, те же мейкфайлы генерит). И у меня получается продуктивно работать.

Надо нафигачить простейший SVM? Так, что у нас там есть… liblinear, libsvm, dlib. Мне ещё потом ручками надо будет запрогать логистическую регрессию, то есть, минимизировать функцию, в dilb это тоже есть, да ещё и в обобщённом виде, значит, выбираем его. Какой там API… За полчасика посмотрели, изучили, примеры почитали, можно писать. Ой, медленно, надо для матриц дёргать что-то этакое… О, есть же Intel MKL! А его как раз dlib тоже поддерживает! Пересобрали dlib с поддержкой MKL, вау, псевдообратная Пенроуза-Мура для матрицы 200000×200000 теперь берётся не 600 секунд, а 50!

Надо распарсить сложный формат с исходными данными теперь — набросали на хаскеле/attoparsec прототип, убедились, что всё парсится, грамматику файла мы вывели правильно, берём Boost.Spirit, 10 минут тратим на переписывание с аттопарсековского eDSL на спиритовский, 20 — на борьбу с компилятором, попутно быстренько изучаем, как в Boost.Phoenix сделать обобщённую ленивую функцию для parser semantic action.

Надо теперь запрогать символьную регрессию — открываем свой диплом от 2012 года, пишем прототип на хаскеле, запускаем, всё ок, переписываем, отключив мозг, на плюсах, профилируем, убеждаемся, что тормозит вычисление производных, смотрим, чем бы генерить код, ой, нет, llvm — оверкилл, пойду напишу свой компилятор в обратную польскую, оно более cache-friendly будет, и правда, теперь производительность устраивает.

Как-то так, ага. Если стеки-библиотеки и надо изучать, то лишь для каких-то задач, специфичных для области, что, похоже, идёт совсем вразрез с посылом данного поста.

Посмотрел я, короче, на это всё околоджаваскриптовое действо и в очередной раз порадовался, что я занимаюсь скучным, неинтересным, незрелищным вычислительным бекендом.
make — стандартный инструмент. И будет стандартным и через 5, и через 10 лет.

webpack такой же стандартный инструмент фронтэнда (да уже и не только)


Надо нафигачить простейший SVM? Так, что у нас там есть… liblinear, libsvm, dlib. Мне ещё потом ручками надо будет запрогать логистическую регрессию, то есть, минимизировать функцию, в dilb это тоже есть, да ещё и в обобщённом виде, значит, выбираем его. Какой там API… За полчасика посмотрели, изучили, примеры почитали, можно писать. Ой, медленно, надо для матриц дёргать что-то этакое… О, есть же Intel MKL! А его как раз dlib тоже поддерживает! Пересобрали dlib с поддержкой MKL, вау, псевдообратная Пенроуза-Мура для матрицы 200000×200000 теперь берётся не 600 секунд, а 50!

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

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

Зачем?

У вас был вопрос о том, где достаточно знать только язык, чтобы продуктивно работать. Вот язык, вот domain-specific-либы, которые уменьшают сложность задачи, а не языка, всё.
> А теперь то же самое но с гуями

Вы теплое с мяким зачем сравнваете? В браузере вы сделаете из всего перечисленного только гуй

В КАКОМ броузере? Вы понимаете что если сравнивать разработку фронтенда с разработкой пользовательского десктопного ПО то правильнее будет брать не разработку под одну платформу а сразу под весь зоопарк. Никто же приходит со словами — а сваяй ка мне, любезный, фронт под хром 52 версии. Никаких стилей, проект развиваться не будет, вот ТЗ — оно актуально на ближайшие 10 лет. (в таком раскладе да — бабель не нужен, куфсе меняем на custom elements, на webpack забиваем — делаем сборку с npm парой самописный скриптов и радуемся жизни) Но нет такого, как правило хотят весь зоопарк за редкими исключениями (кому то старые ослы не нужны, кто то на мобильные может не заморачиваться — по разному) Тут возникает бабель, потому что фрагментация и хочется писать на прямом языке под старые броузеры.
Далее — раз уж мы пишем приложение на все платформы, все для пользователя — давайте уже его писать так что бы пользователь (владелец сайта) мог легко менять темы (путем эксплуатации верстальщика). Ага?  Да, для фронта для этого нужны инструменты для стилей. Тут уже всякие less и иже сними с поддержкой в webpack.
jsx (tsx) — шикарный инструмент который можно использовать и без реакта, спокойно переключаясь от верстки к коду — то есть в процессе программирования DOM елемент объявляется и используется и как верстка и как js объект. Темплейты становятся не нужны. Опять же tsx/jsx транспайлить удобено webpack-ом (просто потому что он изначально спроектирован для сборки фронтов)
Про сборку всего этого ливера в один модуль — в статье откровенный бред, webpack легко и непринуждено позволяет собирать в несколько, группировать общеиспользуемые.
Не хочу аппелировать к мысли о том что миллионы леммингов не ошибаются — но в этой ситуации прежде чем отмахнуться со словами "это не надо" может лучше сначала подумать — а зачем эти люди разрабатывают и использует эти инструменты? Можно спросить у самих этих людей, если сам сообразить не можешь. Но не надо натягивать свой опыт в ДРУГОЙ области к пониманию этой. Ведь по большому счету даже если взять только фронтенд — задачи которые перед ним ставятся — не ставятся в промышленных масштабах больше нигде. Никто не разрабатывет софт который ДОЛЖЕН работать на десятках платформ. Никто не разрабатывает софт который ДОЛЖЕН компилироваться десятком компиляторов. Не так часто к софту предъявляется требование легкой кастомизации интерфейса. Просто это разные области и соответсвенно разные инструменты.
А ведь кроме фронта есть расширения для броузеров,  есть кодогенерация (swagger/raml) есть много чего чего нет в других нишах. Тут как в ресторане: не нравится — не ходи )

> Никто не разрабатывет софт который ДОЛЖЕН работать на десятках платформ. Никто не разрабатывает софт который ДОЛЖЕН компилироваться десятком компиляторов

Вы верстаете странички для браузера

Нет. Не просто странички и не для одного броузера.
Так то я пишу spa, расширения для броузеров и полный фарш (фронт/бэк, кодогенерация на swagger + хранимки на plv8 вместо этих ваших orm) Это все на typescript.

> Это все на typescript
Бедняга
Вы понимаете что если сравнивать разработку фронтенда с разработкой пользовательского десктопного ПО то правильнее будет брать не разработку под одну платформу а сразу под весь зоопарк.

Я не разрабатываю пользовательское десктопное ПО. Это серверное ПО.

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

> webpack такой же стандартный инструмент
Как минимум до конца года. А там глядишь новый «стандарт» родится
webpack такой же стандартный инструмент фронтэнда (да уже и не только)

Для библиотеки, которой судя по ченжлогам еще трех лет нет смелое утверждение

стандарт это не то чему 10 лет а то что в мейнстриме (если мы говорим о стандартах де факто) Ок, расскажите мне про сборку фронта при помощи make+configure (я знаю что это возможно, более того — я собирал такой проект — именно это позволяет мне сравнивать трудозатраты)
И это не либа и даже не таск раннер — это билдер.

стандарт это не то чему 10 лет а то что в мейнстриме

Когда-то в мейнстриме были хаки для IE, который не поддерижвал стандарты. Как это назвать по вашей логике? :)

Вы считаете что в то время это не было стандартом?

Я, как и многие, считаю, что это были костыли, а не стандарт :)

На всякий случай напомню — мы говорим о стандартах де факто (не де юре) Любой костыль может стать стандартом если он общепризнан. И кануть в лету — если в нем уже нет необходимости.

Ну то есть вы предлагает называть костылестроение — стандартом и делать вид, что это нормально, потому что все так делают? Серьёзно? :)

Нет, я предлагаю признать тот факт что когда все делают костыли — делать костыли — это стандарт. Независимо от того нравится нам это или нет.

Вы сейчас доброй половине комментаторов мозг взорвали
Я бы еще добавил что из-за бездумного использования реакта и других «virtual dom» либ появляется новый пласт проблем на ровном месте и иногда люди в прямом смысле кушают кактус и просят еще. Реальный пример из разрабатываемого сейчас проекта:

Необходимо запилить с нуля сервис для визуализации. Множество кастомных чартов со всякими плюшками. Для визуализации понятное дело выбран d3.js, ибо адекватных аналогов по сути дела нет, если нужен баланс между готовыми фишками и широкой кастомизацией. Но поставлять при этом надо не только голые чарты, а еще несколько кусков, то есть требуется компонентный подход. Ну и естественно выбор (не мой, меня к проекту подрубили уже слишком поздно) пал на React.

И тут начинается самое интересное. В реакте все крутится вокруг virtual dom, а в d3 вокруг обычного дом. Хочешь чтобы эти 2 вещи работали друг с другом как надо? Вот тебе мегакостыль под названием ReactFauxDom (по сути дела лайтовый рескин jsdom). Подрубил, сделал все — работает, можно успокоится. По крайней мере так думал ведущий разработчик, пока не прилетел таск на запиливание анимации. И тут выяснилось что хрен тебе а не анимация. Либо иди нафиг, либо пили мегакостыли. После гуглинга самым «лучшим» из костылей оказался вот этот. Я когда увидел реализацию, у меня чуть глаза на лоб не вылезли. Люди на полном серьезе предлагают на каждом фрейме анимации (16ms) обновлять состояние компонента! Тут конечно можно во всем винить разработчика, который выбрал такой стек, но чтобы бы пришлось делать, если бы на проекте, где все изначально было запилено с реактом, пришлось бы вставлять визуализацию с d3? Делать вот такие жуткие вещи, за которые в приличном обществе расстреливать надо?
Ребята из Uber пытаются (небезуспешно) решить ту же проблему — https://github.com/uber/react-vis

Спасибо, интересно очень именно про негативные стороны React узнать. Потому что все пишут про его положительные стороны, а вот недостатки обходят стороной. А ведь в них вся соль. Мне вот совершенно непонятно пока, как в реакте с его уровнем абстракции от DOM делать какие-то супер динамичные вещи.


К примеру, у меня есть проект WYSIWYG редактора, который юзает голый DOM (и именно это позволило сделать такой UI, а также кастомный undo/redo стек для DOM):



Я понятия не имею как подобное можно было бы реализовать в рамках модели React. Но очень интересно.

Вау, очень круто!
По-моему, это достойно отдельной статьи, скромного 100500-го коммента к шуточной статье.

Всему свое время. Просто его код пока еще слишком плох для opensource (много проприетарщины и левых зависимостей), и я хочу его отрефакторить перед публикацией, но никак не могу найти время на это. Тут очень важно maintainability, потому что у меня нет времени это развивать самому (мне за это не платят), а комьюнити могло бы помочь. Вообще-то он валяется на гитхабе, но пока что в реально стремном состоянии, not for human consumption.

Обалдеть. Скорее на гитхаб, уже хочу использовать у себя :)
Так ведь уже: https://github.com/xpl/wyg
Нет, оно голый DOM не юзает — слишком зависит на отдейной либе. Мало того, у меня он вообще паникует

По сравнению с реактом — это голый дом, т.к. к нему прямой доступ, оно работает напрямую с его узлами (без виртуальной прослойки). На реакте я такое не знаю как сделать, мне кажется это просто невозможно на данный момент. По поводу эксепшенов я хз, я это вообще не планировал публиковать пока что, пока не отвяжу это от проприетарных библиотек. Зря я ссылку выложил.

Взгляните на slate.

О, замечательная штука. Меня правда больше заинтересовал Draft.js сейчас фейсбучный — т.к. он куда более примитивный, для образовательных целей больше подходит. В общем, щас буду думать, как такую механику взаимодействия реализовать для React-based редакторов, может это не так уж и сложно, как кажется. Потому что очень хочется перейти на VirtualDOM и иммутабельность состояния — плюсы от этого перевешивают все минусы, когда речь заходит о такой сложной вещи, как современные контент-редакторы.

Посмотрите еще alloyeditor.
Только что увидел этот комментарий… На случай если вдруг проблема еще актуальна — в React на самом деле все неплохо с подключением чужеродных компонентов: есть componentDidMount, есть componentWillUnmount, есть componentDidUpdate, и есть ReactDOM.findDOMNode который можно использовать в этих трех колбеках.
НЛО прилетело и опубликовало эту надпись здесь
Когда весь компонент — просто обертка для чужеродного кода, генерирующего весь свой DOM самостоятельно, функциональность React.createRef() избыточна.
Там другая проблема. Чарты создаются в одном сервисе, который их рендерит на сервере и посылает в итоге готовое svg. То есть вся логика построения чарта целиком сокрыта на сервере и после рендера чарта, все логические связи утеряны (по сути дела посылается что-то типа картинки, к которой привязаны простые хуки, аля показать тултип при наведении на эту полоску). А чарт уже маунтится в другой аппе. Тултипы показать можно, примитивные анимации можно, но все что связано со сложной логикой (например бар чарты где все разбито на группы, внутри которых своя логика и хочется все анимировать последовательной лесенкой) просто начисто теряется. Ну и мой комментарий уж очень старый, я тогда в реакте только начинал разбираться, но по правде говоря конкретно эта проблема так никуда и не сдвинулась, да и все забили.
я вот ни разу не программист, но даже я 2 года назад писал о грядущей энтропии
http://radiokot.ru/forum/viewtopic.php?f=17&t=109995
НЛО прилетело и опубликовало эту надпись здесь
first class citizen

я даже не знаю, что это такое

(ну и замыканий в довесок).

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

Если это троллинг, то я на него почти повёлся. В ином случае вам стоит изучить Haskell (или его браузерную инкарнацию Elm), иначе ну нельзя же таким быть! Особенно вот это понравилось:


питон пробовал — синтаксис не понравился, скобочек нет
Если это троллинг

да у меня что ни пост, то все думают, что троллинг
чего тролльного в моем посте и на что ты повелся?

В ином случае вам стоит изучить Haskell

а зачем он мне? я только краем уха слышал про него

Особенно вот это понравилось

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

Смешно как раз то, что от скобочек-то кровь из глаз и течет, а вы это «приятным синтаксисом» называете. Вспоминается автомобиль Гомера Симпсона сразу.


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

В Си и Паскале можно создать функцию-переменную и передать ее в качестве пареметра в другую функцию
можно передать имя функции в функцию обратного вызова, создать переменную нельзя
что скобочки не ставятся — это косяк, я где-то когда-то упоминал об этом
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
так это присвоение адреса функции, мне как-то для переключения эффектов на светодиодной ленте потребовалось переключать функции
т.е. они статически забиты в памяти и тупо выполняются друг за другом, а хотелось включать их по желанию
я подумал, что у функции должен быть адрес и этот адрес можно как-то указать в переменной или массиве и потом выбирать индекс

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

тут я четко вижу, что я присвоил переменно ор адрес функции с именем doubling
один косяк — нет скобочек после имени, что вызывает путанницу при чтении незнакомого кода

ну и в яваскрипте я даже не знаю, зачем это нужно
НЛО прилетело и опубликовало эту надпись здесь
А зачем там скобки при взятии адреса, если там нет вызова функции?

чтобы было понятно, что это адрес функции, а не переменной

Для того же самого. Плюс возможность использования замыканий.

как-то слишком сложно там все
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
с классических языков с четкой структурой и типизацией, где функция никак не может быть переменной

Вы ещё, наверное, и C++ современный не желаете осиливать?


auto less = [](auto a, auto&& b) { return a < b; };
читал про новые спецификации и понял, что и это катится туда же, так что не стал осиливать, да и особо не силен в нем
не стал осиливать
да и особо не силен

Practice makes perfect… Или «дорогу осилит идущий». Вы же просто не хотите идти.

Вы же просто не хотите идти

а кто хочет идти по грязи?
я помню ит 16 лет назад и что сейчас
все усложняется, нет разумной достаточности

то же самое с телефонами — процессоры с кучей ядер и гигагерцами, экраны с таким разрешением, что мой 24" монитор отдыхает
и для чего это все, если этот телефон еле тянет 1 день? поэтому я юзаю смартфон 5 летней давности, который даже на батарейке 5 летней работает больше суток
мы покупали одинаковые телефоны с корешем в 2011 году, а он сменил уже кучу телефонов за это время

вот даже посмотри на редактор для каментов тут — есть куча ненужных кнопок, но самая нужная кнопка цитирования не вставляет маркированный текс
а эта фишка была реализована много лет назад на форуме ixbt

зачем мне изучать сложные языки, системы, железо, если они никто не делает простых и полезных вещей?

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

Насчет телефонов я с вами согласен. Я вообще телефон не использую уже пару лет как — не хочу кормить зажравшихся операторов связи, которые отчаянно не хотят быть просто «трубой для данных», и ведут себя как цыгане на рынке, пытаясь обобрать пользователя до последней копейки. Это не партнерство, это не сотрудничество — это воровство… И бороться с этим можно только прекратив эти «отношения». Но это так, оффтоп :)


Но если вы думаете, что концепция «функций как объектов первого класса (first class citizen)» и замыканий вам подобным образом чем-то навредит, обокрав ваше внимание и время — то это вы зря. Мне вот есть с чем сравнивать, могу вас уверить, что это вас только обогатит, сократив ваши трудозатраты. Ну это конечно, если вы собираетесь зарабатывать написанием кода. В ином случае вам это, действительно, не нужно...

Да не больше, чем в среднем по больнице.
Всегда будут люди, кому это месиво будет по нраву, ещё и добавки просить будут ;)
Самым нормальным из всего этого месива я считаю scss и подобные вещи. Прост потому, что они не усложняют работу, а наоборот — упрощают.
С PostCSS SCSS потерял актуальность :D
Фу. Даже ванильный CSS лучше этого…
А как в этом ванильном CSS получить импорты, нестинг, переменные?
Немного не понял, чем он потерял актуальность, если можно писать тот же SCSS-код и обрабатывать его после этого PostCSS-модулями. У меня воркфлоу вообще построен так, что gulp вызывает autoprefixer, node-sass, csso и sourcemaps, т.е. PostCSS не дает мне ничего нового.
Через год:
— А что насчет React?
— Фу
— Фу??
— ФУУ!!!
React, может, и будет «фу». Но не его идея. Она, как мне кажется, — нечто более фундаментальное, сродни маленькому научному открытию (как и промисы с async-await синтаксисом). Вроде на поверхности все, а вот, только в 201*-х годах появилось. Так бывает: у инков вон тоже колеса не было изобретено, когда к ним испанцы приплыли.
А что такого в реакте? Мне напоминает это smarty из мира php, когда каждый говнокодил свой фреймворк со smarty, который по сути тупой шаблонизатор, а не какой-то архитектурный каркас. Сейчас переписываем старое приложение с бэкбона на реакт с редюксом, по ощущениям не только код усложнился, но и стало медленнее, вся прелесть виртуального дома съедается 100500 обёртками.

сравнивать jsx и smarty немного некорректно — это перпендикулярные вещи. А кроме jsx в реакте нет ничего что выживет после принятия custom elements. Как только они перестанут быть драфтом — имхо, они порвут всех на районе. Биндинги и иммутабельность к ним спокойно прикручивается либами, да и сам реакт можно прикрутить, на переходный период, если не хочется терять наработки.

Ну а как же реактивность? Реакт — это же не только абстракция для кастомных элементов.

Для реативности такой монстр не нужен — достаточно Proxy. На мой взгляд, не навязываю но говорю достаточно настойчиво — один свой проект решил реализовать без оглядки на совместимость, так как хочется, для души так сказать. Так вот на современном js (typescript точнее) и современных броузерах все эти чудесные фреймворки отлетают как шелуха, заменяясь где парой строк где одним небольшим модулем. Что то уже в процессе устаканилось, что то еще формируется — но в общем и целом — мое мнение, повторюсь, react не выживет (по крайней мере в том виде что он есть сейчас) Связка tsx + custom elements + Proxy порвала все мои притязания (причем без shadow dom и templates) Может как нибудь напишу статью подробнее — так в одном комментарии все не разберешь и не аргументируешь, так что воспринимайте как мою хотелку, не более )

Сами custom elements не решают основную проблему, которую решает реакт — проблему рендеринга из динамических данных. Именно поэтому React как раз перпендикулярная им вещь. В доках реакта где-то даже есть заметка, как юзать реакт вместе с custom elements.


«Убить» реакт мог бы LazyDOM — это нативная браузерная реализация VirtualDOM, которая основана на DOM API (т.е. виртуальные элементы имеют тот же API что реальные дом узлы — что позволяет юзать их вместе с любым старым кодом, который основан на манипуляциях с реальным DOM, типа джиквери плагинов). Но это пока только экспериментальная концепция.

В самом реакте юзать кастомы геморройно да и не надо. А вот в кастомах использовать реакт — да, можно и в принципе (на первый взгляд) может даже имеет смысл. А биндинги и реактивность, как я уже выше ответил — легко реализуется через Proxy.

Интересно было бы посмотреть на proxy-based решения. Я сам недавно достаточно много времени посвятил исследованиям возможностей Proxy для реактивности, но пришел к выводу что модель React сильнее, т.к. не требует заворачивания данных в какие-то врапперы, т.е. она менее инвазивна.

Не будет ли реализация на основе прокси иметь те же ограничения и слабости, что и Нокаут?

Вот смех смехом, но мне знакомый как раз недавно рассказывал историю ровно про это.
Какой-то хакатон.
Один чувак пытается поднять всю ниииобозримую инфраструктуру, не успевает, говорит ок, отосплюсь — закончу, а второй за час пишет один .html с jquery внутри, который делает ровно то что нужно. Да, его не расширить путем написания конфига с каким-нибудь препроцессором, там нет автосборки, минификации, линтера, bowera grunta с gulp'ом, там нет react'a и всей прочей хипстотни. Но он просто работал.
Самый смак, что когда первому показали результат — он просто не понял что сделали, в его категориях просто не было такого варианта.
Оно просто работает до какого-то момента, а потом поддерживать такой код на jQuery с кучей ручных DOM-манипуляций, без внятной архитектуры становится гораздо сложнее и дороже, чем, например, на React.
Да я ж разве спорю?
Вопрос в том, что:
Я щас делаю простое приложение — обычный TODO-лист, используя HTML, CSS и JavaScript

Ну и в том, что доживет ли кто-нибудь из этих проектов до стадии, когда эта разница в поддержке станет заметна без микроскопа

А вот что реально пугает — так это то, что некоторые люди, за всем фасадом просто забывают (или не знают, что пугает еще больше), что там, внутре неонка, по прежнему все тот же DOM/CSS/HTML и все тот же JS/ES 5.x со всеми своими родовыми травмами.
В результате мы подошли к тому, что проблемы в «некоторых людях», а не в технологиях
Мы вот 6 месяцев девелопим продукт и я до сих пор вижу как все можно было написать в 3 раза короче на джейквери с 5-ю плагинами и было бы понятней чем вся эта лапша реактная, которую 3 девелопера пишут каждый в своем стиле.

И во столько же раз быстрее. Где эта грань, когда становится легче на реакте поддерживать, проходит?
Ну если Ваше приложение прекрасно делается из 5 плагинов на jQuery, тогда зачем Вам React?
Впрочем, у меня опыт абсолютно противоположный.
Приказ сверху.
И почему разный стиль 3х девелоперов — это проблема Реакта?
Скорее общая проблема новых фреймворков. Каждый тащит собой какие-то привычки из других.
как все усложнилось )

И одновременно стало проще — но на другом уровне. Такой стек технологий ведь не просто так возник, это именно ответ на вызовы современности, это реакция на необходимость делать вещи, которые лет 5 назад были просто немыслимы из-за сложности реализации.


То есть оно «все усложнилось» разве что только в какой-то статичной системе отсчета… ну типа, если вы в 2016 все еще ориентируетесь на проекты уровня 2008 года, то это действительно кажется чем-то безумным. Я занимаюсь веб-фронтендом примерно с того года как раз, и прекрасно помню, как я тогда несколько недель (на голом DOM / HTML / CSS) возился с проектом, на который сегодня у меня ушел бы один рабочий день. Тогда просто не было таких инструментов.

Хм, а что по сути изменилось с 2011 годом(пять лет назад) кроме большего распространения мобилок для фронта?
Браузеры остались те же, CSS/HTML/JS остался тот же, сегментация увеличилась в разы, но это тяжело считать позитивным фактором. Мы научились героически преодолевать проблемы, которые сами создаем?
Вот-вот. Angular в 2010 родился. Так что two-way binding можно было и тогда, если не раньше. По удобству он не сильно отличается от реакта.

А то что знатные веб-програмисты любят обмазываться всякими gulp-ами и yeoman-ами — это их выбор, который на конечный результат влияет не так сильно, как им кажется:

Браузер поддерживает gz-сжатие, так что предварительно сжимать текстовые файлы не не так уж и нужно (по крайней мере пока у вас не 50 мегабайт кода и верстки за раз)

Современные браузеры открывают с десяток keep-alive соединений на каждой странице и выкачивают через них все необходимые ресурсы с сервера. На другой стороне nginx может отдавать сотни тысяч файлов особо не напрягаясь

Так скажите мне, зачем вы сжимаете и склеиваете?

Возьмем для примера js-рантайм прекрасного парсера antlr4. В разобранном виде 64 файла, 640 килобайт + обязательно require.js. В .gz — те же 64 файла, 240кб. Плюс десяток соединений все-таки довольно долго забирает 64 файла.


В склеенном и минифицированном — один файл 160 кб. Склеенный и минифицированный в .gz — 38кб. Все еще не понятно зачем?


А в проекте у нас например уже в районе 300 своих js-файлов. Считать оверхед для всего проекта я не буду, мысль понятна, думаю.

Сначала я подивился, что такая большая разница (240кб против 38кб) а потом увидел, что каждый исходный файл содержит в начале текст BSD лицензии )

> Плюс десяток соединений все-таки довольно долго забирает 64 файла

В моих изысканиях не более чем в полтора раза для 50 маленьких файлов

Да, и такие чудеса встречаются. Самое интересное что они сами никаких скриптов для сборки не предоставляют и официально предлагают использовать через require в таком виде, в каком она есть. И "из коробки" оно не собирается, приходится чуть-чуть дополнять.


В моих изысканиях не более чем в полтора раза для 50 маленьких файлов

Полтора раза — это очень много, я тут за каждую 0.1 секунды борюсь для нашего довольно тяжелого приложения)


Ну и как я уже написал проект — он ведь не только из парсера состоит. Есть еще некоторое количество вендорских библиотек и очень много своих файлов. Плюс, как правильно заметили ниже, браузер просто не умеет работать с es6 imports.


А еще амазоновский балансер до сих пор не поддерживает http/2, который мог бы частично решить проблему.

Уже поддерживает — https://aws.amazon.com/blogs/aws/new-aws-application-load-balancer/

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

Ну склеивать удобно хотя бы потому, что браузер не поддерживает директивы import и require. А любой более-менее сложный проект это сотни файлов, связанных такими зависимостями.


Каким образом вы это на HTML страничку доставите? Будете вручную script теги прописывать для каждого, еще и вручную нужный порядок подключения высчитывая?


Конечно же, вы возьмете webpack, укажете ему «точку входа» (js-файл), и он разрешит все дерево зависимостей, высрав это в один файл, который вы можете банальным script тегом подключить. Как бонус — вебпак поддерживает горячую перезагрузку модулей.


Я вот буквально прямо щас настраиваю у нас в сервере Webpack HMR (hot module replacement) + React HotReload. Очень удобная вещь — я жму Ctrl-S в редактируемом модуле, и моментально получаю в браузере обновленный код, без перезагрузки страницы. А поскольку архитектура React/Redux предполагает разделение кода и данных, то при такой замене кода «на горячую», даже не теряется состояние моих компонентов. Это очень круто и дает 100% буста продуктивности.

> Каким образом вы это на HTML страничку доставите?

Так и делал. Если сторонняя библиотека, то подключаю ее через тег script. Если своя, неделимая либа, склеиваю (cat 1.js 2.js… > lib.js). Если просто файлы проекта — подключаю по отдельности. Потому-что на некоторых страницах требуется лишь часть этих файлов.

> Будете вручную script теги прописывать для каждого, еще и вручную нужный порядок подключения высчитывая?

Вы тоже вручную прописываете. причем сильно больше прописываете, т.к. import-ы надо дублировать в каждом файле

imprt'ы прописывает IDE. На них не нужно отвлекаться.

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


А у вас получается делокализация — скажем, я поменял модуль A так, что он теперь зависит от модуля B. И эту информацию мне нужно добавить в какое-то совершенно третье место («главный заголовочный файл», со плоским списокм всех зависимостей), в котором никак не отражена связь между модулями. Это значит, что если модуль A перестанет зависеть от B, то «мусорная» зависимость с высокой вероятностью останется в том третьем файле, потому что вы забудете про неё. Или кто-нибудь еще забудет. В общем, у меня был опыт разработки проекта где именно таким образом все делалось — я не юзал import/require для декларирования межмодульных зависимостей, и поимел все возможные связанные с этим проблемы. Самая жесть началась, когда я попытался сделать свой код re-usable, расшарив его между многими проектами. Сразу же возникает такого рода проблема, что вам нужно во всех этих проектах менять список зависимостей, когда в каком-то модуле что-то меняется. Это приводило к труднообнаружимым багам, к избыточности кода, и так далее.


Если бы я с самого начала использовал import/require и автоматическое разрешение зависимостей (webpack), то сэкономил бы кучу времени...

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

Во, у меня как раз такой проект под боком. Дали команде пионеров(стандартный путь: бывшие рубиянки -> node.js -> js frontend). Пионеры сразу натаскали в прект целую пачку модных технологий es6, react и redux, с кучей дополнительных библиотек, общим счетом под 1к модулей и сели надрачивать на ЧИСТУЮ ФУНКЦИОНАЛЬНОСТЬ и ИММУТАБЕЛЬНОСТЬ.
Причем это АРХИТЕКТУРА за два-три месяца уже успела несколько раз поменяться, тесты написанные вначале сломались, а чинить их никто не собирается, но зато появился новый красивый дэшборд для вебпака, который нужно скорее добавить в репозиторий проекта.
Вопрос «Успеете ли вы до дедлайна предоставить какую-то рабочую версию» был встречен недоумением и обидками.
Так это не в технологиях проблема ведь, а в «пионерах» :)
В пересечении множеств «пионеры» и «модные технологии» :)
Половине технологий год с хвостиком, поэтому все по умолчанию «пионеры».
Стерпер из двухтысячных со своим jquery и грязными руками пытается влезть в современную разработку, которая стала такой из-за общей ущербности html-инфраструктуры и попытки делать красиво и правильно поверх html и браузеров.
Да, если бы убрали html и браузеры, то веб разработка бы взлетела.
Лет 20-25 назад разработку перевернуло появление IDE — Integrated Development Environment. Delphi, VisualStudio и т.п. Это не просто редактор кода, это ВСЁ что было нужно разработчику чтобы работать. Никаких тебе десятков инструментов разного качества от разных разработчиков.
Сейчас в вебе все идет почему-то в обратную сторону.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.