Чем отличаются JavaScript и ECMAScript?

https://medium.freecodecamp.org/whats-the-difference-between-javascript-and-ecmascript-cba48c73a2b5
  • Перевод
Перевод What’s the difference between JavaScript and ECMAScript?

Как-то мы попробовали гуглить «различие между JavaScript и ECMAScript».

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

«ECMAScript — это стандарт».
«JavaScript — это стандарт».
«ECMAScript — это спецификация».
«JavaScript — это реализация стандарта ECMAScript».
«ECMAScript — стандартизованный JavaScript».
«ECMAScript — это язык».
«JavaScript — это диалект ECMAScript».
«ECMAScript — это JavaScript».


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

В этой статье представлено наше понимание различий между JavaScript и ECMAScript. Статья написана для тех, кто знаком с JavaScript, но хочет получить более четкое представление о его взаимоотношениях с ECMAScript, веб-браузерами, Babel и так далее. Вы также узнаете о скриптовых языках, движках JavaScript и средах выполнения JavaScript.

Ну что, погнали.

Словарь JavaScript/ECMAScript


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

Ecma International


Организация, которая создает стандарты для технологий.


Чтобы проиллюстрировать пример «стандарта» (хотя и созданного не в Ecma): вспомните обо всех клавиатурах, которые вы когда-либо использовали. В подавляющем большинстве случаев раскладка была одинаковой? А пробел, клавиша Enter, курсорные клавиши? Цифры находились в верхнем ряду? Это объясняется тем, что большинство разработчиков используют при создании дизайна клавиатуры стандарт раскладки QWERTY.

ECMA-262


Это стандарт, изданный Ecma International. В нём прописана спецификация скриптового языка общего назначения.


ECMA-262 — это стандарт, подобный QWERTY, только представляющий собой спецификацию скриптового языка, называющегося ECMAScript.

ECMA-262 можно считать учётным номером ECMAScript.


ECMA-260, ECMA-261, ECMA-262. А вот и ECMAScript.

Скриптовый язык


Язык программирования, созданный для работы с существующим объектом или системой.

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

ECMAScript


Описанная в ECMA-262 спецификация создания скриптового языка общего назначения.

Синоним: спецификация ECMAScript.


«ECMA-262» — это название и стандарта, и спецификации скриптового языка ECMAScript.

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


Выдержка из спецификации языка ECMAScript 2017. Документ состоит примерно из 900 страниц, если вы ищете, что почитать на досуге.

JavaScript


Скриптовый язык общего назначения, соответствующий спецификации ECMAScript.

Это диалект языка ECMAScript.



JavaScript — мой любимый язык программирования, пропитанный ароматом кофе. ECMAScript — это спецификация, на которой он основан. Из спецификации ECMAScript вы узнаете, как создать скриптовый язык, а из документации JavaScript — как использовать скриптовый язык.

Когда люди называют JavaScript «диалектом языка ECMAScript», они имеют в виду то же самое, что и при упоминании о диалектах английского, французского или китайского языка. Диалект большую часть своего лексикона и синтаксиса наследует из родительского языка, от которого при этом заметно отличается.

Как сказано в ECMA-262, JavaScript в основном реализует спецификацию ECMAScript, но с некоторыми отличиями. Mozilla в общих чертах обрисовала свойства JavaScript, не характерные для ECMAScript:


Скриншот от 3 сентября 2017 года. Это список экспериментально проверенных характерных особенностей JavaScript, которые не являются частью ECMAScript (по крайней мере, пока).

JavaScript-движок


Программа или интерпретатор, способный понимать и выполнять JavaScript-код.

Синонимы: интерпретатор JavaScript, реализация JavaScript.


JavaScript-движки обычно используются в веб-браузерах, включая V8 в Chrome, SpiderMonkey в Firefox и Chakra в Edge. Каждый движок подобен языковому модулю, который позволяет приложению поддерживать определенное подмножество языка JavaScript.

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

Эта аналогия помогает объяснить некоторые особенности браузера:



Разное быстродействие браузеров


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



Разная поддержка в браузерах


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

Говоря о поддержке в браузерах, обычно упоминают о «совместимости с ECMAScript», а не о «совместимости с JavaScript», хотя JavaScript-движки детально анализируют и выполняют… JavaScript. Звучит запутанно, позвольте объяснить.


Это часть таблицы, посвящённой браузерной поддержке ECMAScript. Версии JavaScript в ней не упоминаются.

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

Поэтому разработчики, как правило, задают вопросы вроде «Какую версию ECMAScript поддерживает этот браузер?» или «Какие функции ECMAScript поддерживает этот браузер?» Они хотят знать, удалось ли Google, Mozilla и Microsoft наделить JavaScript-движки (соответственно V8, SpiderMonkey и Chakra) свойствами, описанными в последней версии ECMAScript.

Ответы на многие вопросы вы найдёте в Таблице совместимости ECMAScript.

Если выйдет новая версия ECMAScript, то в JavaScript-движках не появятся разом все нововведения. Они будут внедряться постепенно, релиз за релизом, как это видно на примере журнала изменений JavaScript в Firefox:


Какие-то части стандартов ES2015 и ES2017 были реализованы в JavaScript-движке SpiderMonkey в браузере Firefox 50. Ещё раньше были реализованы другие части ES2015 и ES2017, и это продолжилось в последующих версиях.

Среда выполнения JavaScript


В этой среде выполняется JavaScript-код и интерпретируется JavaScript-движком. Среда выполнения предоставляет хост-объекты, на которых и с которыми может работать JavaScript.

Синонимы: хост-среда (Host environment).


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

JavaScript-скрипты могут обращаться к приложениям, потому что те предоставляют «хост-объекты» в среде выполнения. На клиентской стороне средой выполнения JavaScript будет веб-браузер, в котором становятся доступными для манипуляций такие хост-объекты, как окна и HTML-документы. Вы когда-нибудь работали с хост-объектами в виде окна или документа? Такие объекты не являются частью базового JavaScript. Это веб-API, объекты, предоставляемые браузером, действующим как хост-среда JavaScript.

На серверной стороне среда выполнения JavaScript — это Node.js. В Node.js предоставляются связанные с сервером хост-объекты, такие как файловая система, процессы и запросы.

Любопытно, что разные среды выполнения JavaScript могут использовать один и тот же JavaScript-движок. Например, V8 — это движок, используемый в двух совершенно разных средах — в Google Chrome и Node.js.

ECMAScript 6


Это шестая редакция стандарта ECMA-262, внёсшая в спецификацию ECMAScript существенные изменения и улучшения.

Синонимы: ES6, ES2015 и ECMAScript 2015.


С 2015 года Ecma International перешла на ежегодные релизы ECMAScript, и эту версию ECMAScript переименовали с ES6 на ES2015. Ecma International стала называть новые версии спецификации ECMAScript в соответствии с годом выпуска. То есть ES6 и ES2015 — это одно и то же.

Babel


Транспилятор, конвертирующий код ES6 в код ES5.


В ES6 разработчикам доступны замечательные новые функции, но нельзя забывать и о межбраузерной совместимости. Во время написания этой статьи Edge и Internet Explorer поддерживают не все функции из спецификации ES6.

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

Ещё кое-что


Надеюсь, вы узнали что-то для себя новое о JavaScript и ECMAScript. Прежде чем закончить, хотелось бы ещё кое-что разъяснить начинающим веб-разработчикам.

Курица или яйцо


JavaScript был создан в 1996 году. В 1997 году Ecma International предложила стандартизировать JavaScript, и в результате появился ECMAScript. Но поскольку JavaScript соответствует спецификации ECMAScript, JavaScript является примером реализации ECMAScript.

Получается, что ECMAScript основан на JavaScript, а JavaScript основан на ECMAScript.

Да, это смахивает на затёртый кинематографический штамп, когда путешественники во времени становятся своими собственными родителями. Забавно, хотя и немного странно.

Понимаем, что всё здесь сказанное немного вас позабавило, но надеемся, что вы получили пищу для размышлений. Позвольте откланяться.
NIX Solutions 267,04
Компания
Поделиться публикацией
Комментарии 68
  • 0
    Спасибо за доступный материал по сдвигу мозгов в правильную сторону. Увы, голосовать пока еще не могу.
    • –4
      Интересно, и чем же не понравился положительный комментарий? А голосовать не могу по причине неполноценного аккаунта…
      • +3
        Спасибо за положительную оценку! Ваш комментарий опубликован, и он очень греет сердце админа блога :)
        • +4
          А голосовать не могу по причине неполноценного аккаунта…

          Тем, что информация про то, можете ли вы голосовать, или нет — никак не относится к теме статьи, а потому излишня. Тем более выглядит, как выпрашивание кармы. Представьте, что тут будет, если каждый, кто не может голосовать напишет, что он не может голосовать.
          • –4

            Мафия голосовантов, из которых сыпется песок (да, я помню 2005-е), прочно занимает свои позиции и не пускает новичков

            • +3
              Я так и представляю, как у вас в голове рисуется картина, как мы, семья людей с высокой кармой на хабре, сидим за длинным столом, во главе сидит дон Milfgard с розой в пиджаке. У нас слет и мы решаем, кому можно вступить в нашу семью, а кому нет. Новичок, конечно, должен доказать свою верность тем, что убьет учасника, который имеет мнение отличное от нашего. После этого мы всей семьей голосуем ему положительно и он вступает в нашу мафию.

              Я понимаю, что ныть и клянчить карму легче, чем писать объемные технические статьи, но будьте честными хотя-бы с собой.
      • 0
        Итак, JavaScript — это диалект языка ECMAScript.
        В w3schools считают (очевидно, ошибочно) ECMAScript официальным названием JavaScript'а:
        JavaScript was invented by Brendan Eich in 1995, and became an ECMA standard in 1997.
        ECMA-262 is the official name of the standard. ECMAScript is the official name of the language.
        Всё же диалект и официальное название — не одно и то же.
        • +3
          w3schools — это сомнительный сайт с кучей сомнительных туториалов, который никак не связан с W3C

          Лично я рекомендую забанить для себя его в гугле, ведь есть гараздо менее сомнительные сайты той же направленности, например MDN
          • 0
            Вся проблема в том, что гугл часто ставит его первым в результатах поиска (в т.ч. по запросу «javascript versions»), что может часто сбивать с пути истинного новичков.
            • 0
              Это и правда проблема.
        • +1

          Хотелось бы узнать, какие ещё диалекты есть у ECMAScript. Например, является ли ActionScript его диалектом, и если нет, то почему.

          • –2
            ActionScript это адобовская *рень, есть еще TypeScript
            • +3
              Вообще-то это ES4, который не был принят (слишком велики были изменения), поэтому был скачок с ES3 на ES5 как продолжателя с минимальными нововведениями и обратной совместимостью.
              • 0
                Отличный язык, между прочим )
          • 0
            > JavaScript — мой любимый язык программирования, пропитанный ароматом кофе.

            ECMAScript — это спецификация, на которую он забил ))
          • +1
            В наши дни я бы не стал официально называть JavaScript языком. Сейчас это, скорее, семейство языков, как когда то было популярно семейство языков BASIC.
            • 0

              интересно, расскажите поподробнее, почему так

              • +1

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

                • 0

                  Звучит правдиво. У Javascript нет эталонной имплементации, все движки равны между собой и немного отличаются.

              • +5

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

              • 0
                > "[JavaScript] Это диалект языка ECMAScript."

                Если это так, то подскажите, как Брендан Эйх смог его сплагиатить в конце 1995 года, когда ECMAScript 1.0 появился в 1997? Ему рассказал Т-800 или Эммет Браун?
                • +1
                  В конце статьи всё разъяснено
                • –1

                  А я думал, что когда дело дошло до стандартизации, то из-за опасения копирайта на Java часть в названии, её заменили на всякий случай на ECMA. После чего «JavaScript» стал народным названием языка, а ECMAScript официальным.


                  Иначе временной парадоксс и вообще не понятно кто на этом ECMAScript пишет.


                  Не претендую на истинность, версий слишком много

                    • +1

                      Спасибо. Оттуда и почерпнул информацию. Хорошо написано, с удовольствием прочитал второй раз.


                      О себе могу сказать, что пишу на ES2015, всё реже на ES5.


                      А если я скажу, что «пишу на JavaScript» — не сильно конкретизирует и может означать как то, что было на старте тысячелетия с падающими снежинками (при этом нужно обязательно уточнить браузер), так и классы, промисы, импорты и прочие плюшки современности.


                       


                      В заключении к первой статье из цикла об истории JS, пишут такое:


                      На сегодняшний день JavaScript это всего лишь коммерческое название ECMAScript.
                       

                      ИМХО JavaScript — не стандарт, а поле боя для браузерных войн толкающих свои стандарты

                      • 0
                        Могу порекомендовать писать на typescript с указанием нужного таргета в виде es5 / es6 / es2015 / esnext: получаем синтаксис esnext + интерфейсы, enum-ы, модификаторы доступа, async / await, статический контроль типов — и это все без жирного babel-я с кучей плагинов к нему.
                        • 0

                          Множество субъективных и объективных факторов… В частности командная разработка не дадут так просто изменить стек технологий.


                          Кстати es6 / es2015 это разве не одно и то же?


                          ES6 — всё таки стандарт ДжаваСкрипта, а подмножества вроде CoffeScript неплохое поле для обкатки новых идей, самые (недеюсь) годные из которых перекачёвывают в ESNext, а сами подмножества медленно отмирают. Андерс Хейлсберг конечно уважаемый человек, но и его детище может уступить дорогу новому стандарту.


                          За 12 лет привык к динамической типизации, статическую типизацию мне заменяют prop-types и регистровая типизация (смешиваю всякие снейк_кебаб-КамельКейсы для разных типов, в т.ч. для имён файлов)


                          В данный момент не вижу причин усиленно разбираться с TS, но учитывая встроенную поддержку IDE ваша рекомендация прибавила желания попробовать.


                          ЗЫ что-то мне подсказывает, что избавившись от бабеля нельзя просто так взять и избавиться от тяжести той работы которую он выполняет. Я так понимаю у вас уже серьёзный проект с большим количеством кода, сколько времени занимает промежуток от ctrl+s до завершения компиляции?

                          • 0
                            мне заменяют prop-types

                            Они уже deprecated — рекомендуют переходить на ts / flow. flow — это просто типы, т.е все-равно нужен внешний инструмент для их обрезания — тот же бабель с плагином.
                            В данный момент не вижу причин усиленно разбираться с TS

                            Любой js — это валидный ts (с отключенными проверками). Вот от этого знания и следует плясать дальше, постепенно подкручивая гайки на проверки типов и т.п.
                            сколько времени занимает промежуток от ctrl+s до завершения компиляции?

                            Я не фронтендщик, для бекенда достаточно использовать штатный механизм ts для транспиляции: tsc -w. В паре последних версий был прикручен инкрементальный режим + оптимизирована скорость. Вообще, транспайлинг занимает максимум секунду, возможно 3-4 первый раз. Но это сильно зависит от сложности кода и его количества. Для фронтенда, если нужна минификация + бандлинг — могу посоветовать fuse-box.org — заменяет вебпак, любит ts из коробки, летает как самолет.
                            • 0

                               


                              Они уже deprecated

                              Ничего они не deprecated
                               


                              Просто переехали в отдельный пакет из Реакта:


                              https://www.npmjs.com/package/prop-types

                              • 0
                                Ничего они не deprecated

                                Ну я воспользовался формулировкой о «New Deprecation Warnings» с официального сайта: reactjs.org/blog/2017/04/07/react-v15.5.0.html
                                Ну и в консоли писалось:
                                React.PropTypes is deprecated since React 15.5.0, use the npm module prop-types instead

                                Да, отдельный модуль, но нужно ли оно, если валидация происходит только после запуска, а в случае с ts / flow — прямо при написании кода?
                                • –1
                                  Да, отдельный модуль, но нужно ли оно, если валидация происходит только после запуска, а в случае с ts / flow — прямо при написании кода?

                                  Вот именно, что возбраняется React.PropTypes и вместо него рекомендуют использовать отдельный пакет prop-types. Это как бы намекает на выход парадигмы за пределы экосистемы ReactJS, что косвенно подтверждает эффективность.


                                  Ты — бэкендщик, я — фронтендщик, нам Дург друга не понять.


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


                                  Возможно твоя любовь к статической типизации объясняется подходом к разработке при котором приложение может писаться часами, а после запускается и работает.


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


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


                                  ЗЫ я не призываю тебя съехать с TS, скорее изучаю дружественную пати

                                  • +1
                                    Да по-разному, иногда раз в 30 секунд перезапуск, иногда 5 минут. Тут смысл в другом — ts просто не даст тебе написать неправильный код, если ты передашь неправильные параметры в вызов метода или инициализацию данных, если забудешь проинициализировать обязательные поля и т.п — код просто не оттранслируется в js и watcher сразу заорет что есть ошибки. Да, приходится везде прописывать четко типы, но потом, когда добавляются люди на проект и появляется много модулей — все становится гораздо проще согласовывать.
                                    По поводу среды разработки и ошибок: в той же vscode все гораздо приятнее — там валидация делается через фоновый language server в реалтайме и ты ошибки видишь сразу с подчеркиваниями и иногда даже с автоматическими хотфиксами в стиле resharper-а. Про ошибки в рантайме — это плохо, если для нужного функционала нужно ползти долго через несколько промежуточных этапов, ну или пытаться повторить кейс через автотесты со сложно добываемым состоянием окружения.
                                    • 0

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


                                      С PropTypes такая пичаль, что нельзя сделать


                                      static propTypes = {...modificators, ...themes}
                                      

                                      и сохранить подсказки при заполнении пропсов. А приём таки необходимый в некоторых ситуациях, иначе приходится дублировать списки, чтобы оставить PropTypes в примитивном виде. Вся надежда на разработчиков IDE


                                      Наверное стоит объяснить зачем мне это. Проще всего будет на компоненте иконок.


                                      Есть компонент <Icon />, его можно использовать так <Icon search x2 /> и это отрендерит иконку с лупой двойного размера. В таком формате можно получать подсказки к названию иконок, но после разделение пропсов на имена иконок и модификаторы, для последующего использования ключей этих списков внутри класса, часть профита, в виде автодополнения, теряется. Разработчик шторма услышь мои стенанья

                                      • 0
                                        А если метод вызывается не на прямую, а погружен глубоко в недры декораторов, или ещё чего, что его пропускает сквозь себя, это тоже будет работать?

                                        С ts нужно или руками кастовать к нужному типу или к any, чтобы отключить проверку типов. Т.е все-равно какой-то тип нужен.

                                        С PropTypes такая пичаль, что нельзя сделать

                                        Тут скорее всего придется завести интерфейс с указанием доступных полей и использовать его при создании инстанса нового типа — IDE потом будет использовать этот интерфейс для подсказок в интеллисенсе.

                                        <Icon search x2 />

                                        В ts это можно сделать как-то так:
                                        export interface IProps {
                                            search?: boolean;
                                            x2?: boolean;
                                        }
                                        
                                        export class Icon extends React.Component<IProps, {}> {
                                            public render() {
                                                // И вот тут IDE (например, vscode) будет показывать полноценный intellisense с возможными свойствами и их типами.
                                                const search = this.props.search;
                                                const x2 = this.props.x2;
                                                ...
                                            }
                                        }
                                        

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

                                          Есть деструкторы же, так куда лаконичнее:


                                          const { props: { search, x2 }} = this

                                          чем:


                                          const search = this.props.search;
                                          const x2 = this.props.x2;

                                          Так и так мою задачу не решают. Можно наследовать два и более интерфейсов? Свойства интерфейса можно перебирать через .map например?

                                          • 0
                                            Есть деструкторы же

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

                                            Можно наследовать два и более интерфейсов?

                                            Можно реализовывать несколько интерфейсов.

                                            Свойства интерфейса можно перебирать через .map например

                                            Интерфейсы — это сущности времени транспиляции / статической проверки типов (по сути — набор требований, которые должны выполняться для передаваемых инстансов). На выходе получается чистый js безо всяких фишек ts, о каком переборе свойств через .map идет речь?
                                            • –1

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


                                              getPropsWithoutModifiers() {
                                               return _.omitBy(this.props, propInModifiersIntarface)
                                              }
                                              getPropsWithoutThemes() {
                                               return _.find(this.props, nameInThemeInterface) || 'default'
                                              }

                                              Читаю это, норм? Там нашёл, что интерфейсы наследуются так-же как и классы, это здорово. Совсем забыл обо всей этой кухне с тех пор как перестал на PHP писать

                                              • 0
                                                интерфейсы наследуются так-же как и классы, это здорово.

                                                Только не наследуются, а реализуются (implements) — т.е на тип накладываются ограничения-требования и чтобы инстанс объекта мог работать через интерфейс-абстракцию — он должен реализовывать все перечисленные ограничения-требования. Это все проверяется только в IDE / транспайлере, никаких проверок в рантайме нет. Т.е мы максимально закручиваем гайки в момент написания кода и облегчаем рантайм на все уже ненужные проверки типов / значений. Разумеется, все данные, приезжающие снаружи в рантайме, нужно валидировать на совместимость, но дальше все должно работать достаточно стабильно.
                                                • –1
                                                  propTypes кстати тоже автоматически исчезают (как и много другое) при продакшен компиляции сборки.

                                                  В рантайме девелопера конечно остаются, что немного сказывается на производительности, но не критично.

                                                  И раз для данных прибывающих из вне такая пичалька, то все равно приходится использовать нечто вроде prop-types для данных приходящих по API (а у меня это большинство данных)?
                                            • 0
                                              const { props: { search, x2 }} = this

                                              Лучше так:
                                              const { search, x2 } = this.props


                                              Так и так мою задачу не решают. Можно наследовать два и более интерфейсов? Свойства интерфейса можно перебирать через .map например?

                                              Объясните задачу. Если я вас правильно понял, то самое простое:

                                              
                                              type IPropsX2 = { x2: boolean };
                                              type IPropsSearch = { search: boolean };
                                              
                                              type IIconProps = IPropsX2 | IPropsSearch;
                                              
                                              class Icon extends Component<IIconProps> {}
                                              
                                              // или даже так:
                                              
                                              class Icon extends Component<IPropsX2 | IPropsSearch> {
                                              	render () {
                                              		return this.props. // x2|search
                                              	}
                                              }
                                              


                                              Хотя это, скорее IPropsX2 или IPropsSearch. Можно использовать type IIconProps = IPropsX2 | IPropsSearch;. Но для пропсов я предпочитаю вариант с интерфейсами:

                                              
                                              interface IPropsX2 { x2?: boolean }
                                              interface IPropsSearch { search?: boolean }
                                              
                                              interface IIconProps implements IPropsX2, IPropsSearch {}
                                              
                                              class Icon extends Component<IIconProps> {
                                              	render () {
                                              		return this.props. // x2|search
                                              	}
                                              }
                                              


                                              Мар (и другие Дженерик-функции) работают так, как того от них ожидаешь:

                                              
                                              interface IFoo { foo: boolean }
                                              interface IBar { bar: boolean }
                                              
                                              class Item implements Foo, Bar { /* ... */ }
                                              
                                              const items: Item[];
                                              
                                              items.map(it => it.); // тут или it.foo или it.bar
                                              


                                              IDE автодополнит, корректно расчитает возвращаемый тип и вся цепочка будет типизированной.

                                              Ты — бэкендщик, я — фронтендщик, нам Дург друга не понять.

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

                                              
                                              interface IFoo {
                                              	id: number;
                                              	title: string;
                                              }
                                              
                                              inteface IFooListProps {
                                              	items: IFoo[];
                                              }
                                              
                                              class FooList extends Component<IFooListProps> {
                                              
                                              	render () {
                                              		return <ul>{this.props.items.map(this.renderItem)}</ul>;
                                              	}
                                              	
                                              	renderItem(item: IFoo) {
                                              		return <li key={item.id}>{item.title}</li>;
                                              	}
                                              
                                              }
                                              


                                              Как PropTypes будут работать на этом примере? Как говно. Чем они и есть.
                                              • –1
                                                Как PropTypes будут работать на этом примере?

                                                Не очень силён в TS, чтобы точно сказать как себя поведут здесь типы, вижу интерфейсы, а чего там дальше с ними происходит — искТри. Вот вы скажите у вас проптайпы начинают пахнуть или, что? Без TS туда можно свои функции с любыми проверками отправлять. Имхо гибко, не?


                                                const { search, x2 } = this.props

                                                Вы же выносите метод в класс, используете его в соседнем методе. Мой деструктор без проблем позволит добавить в него методы компонента и стейт, а не вермешелить ниже в методе. А вы просто ими не пользуетесь и пишите this.props.items.map(…


                                                На вашем примере это выглядело бы так:


                                                lass FooList extends Component<IFooListProps> {
                                                
                                                    render () {
                                                        const { props: { items }, renderItem }
                                                        return <ul>{items.map(renderItem)}</ul>;
                                                    }
                                                
                                                    renderItem({id, title}: IFoo) {
                                                        return <li key={id}>{title}</li>;
                                                    }
                                                
                                                }

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


                                                «TS интерфейс итерация» у Гугла ничего не дал

                                                • 0
                                                  «TS интерфейс итерация» у Гугла ничего не дал

                                                  а если погуглить на английском: "typescript get interface keys", то найдется релевантный вопрос: https://stackoverflow.com/questions/37214961/is-it-possible-to-loop-through-all-objects-in-an-interface-to-get-key-and-value


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

                                                  • –1
                                                    Конечно я знаю, что можно решить одну и ту же задачу десятками разных способов, это же программирование! Подзадача была такая: исключить дублирование ключей в разных списках, сразу брать их из интерфейсов и иметь возможность работать с их именами после транспиляции.
                                                    И вот кстати решение

                                                    Всем спасибо, было очень интересно узнать о TS, открыл для себя новую тему для чтения. Возможно когда нибудь удастся убедить остальных членов команды это попробовать.
                                                    • 0

                                                      Это не решение, это костыль.


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


                                                      Правильным решением вашей проблемы может быть два варианта


                                                      1. Вместо вливания нескольких свойств themes объявляем одно свойство theme и везде передаем только его.
                                                      2. Использовать существующие библиотеки для темизации, вместо своего решения. Есть ThemeProvider в styled-components, есть независимая библиотека theming. Что характерно, в них обоих параметры темы передаются как раз-таки едиственным свойством theme.
                                                      • 0
                                                        Что характерно, в них обоих параметры темы передаются как раз-таки едиственным свойством theme.

                                                        Вот они не осилили и я тоже должен сдаться по вашему?
                                                        С одним параметром вообще никаких проблем, дело в фишке с автодополнением (и оно у меня кстати работает если не сепарировать пропсы по группам). Спред в пропсы ломает автодополнение.


                                                        Хотя я не пользовался этими инструментами и возможно гоню. Может там текстовое поле с названием темы тоже автодополняется? Попробовал через enum .oneOf([…]), нет эффекта.


                                                        Ещё раз скорректирую свою цель:
                                                        Получение максимально лаконичного решения с сохранением автокомплита в IDE


                                                        Я надеюсь в следующих версиях IDE появится поддержка расширения пропсов из соседних объектов (а когда их очень много, очень хочется хранить их в отдельном файле)


                                                        ЗЫ Я понимаю, что это похоже на хак архитектуры, но может я заразный и такие практики войдут в обиход?

                                                        • 0
                                                          Получение максимально лаконичного решения с сохранением автокомплита в IDE

                                                          IDE предлагает автокомплит на основе статического анализа, а вообще конструкция {...modifiers, ...themes} — динамическая, поэтому поддерживаться не будет в принципе.


                                                          Поэтому выбирайте: либо красивый код для вас, либо понятный для инструментов разработки

                                                          • –1
                                                            Да, вы правы. Я слишком много хочу. Но попробовать стоило. В конечном итоге без этого лишь небольшой ущерб лаконичности, но плюс к архитектуре
                                                            • 0
                                                              {...modifiers, ...themes} — динамическая, поэтому поддерживаться не будет в принципе.

                                                              Почему нет? Для C# это странный подход, но TS вполне справится:
                                                              const modifiers: Mods;
                                                              const themes: Themes;
                                                              const mixed: (Mods & Themes) = { ...modifiers, ...themes }


                                                              Не самая прогрессивная «IDE»:

                                                    • –2
                                                      искТри

                                                      Что это за слово?

                                                      Без TS туда можно свои функции с любыми проверками отправлять. Имхо гибко, не?

                                                      Эти функции можно засунуть только в одно место… — на вход реакт-компонента. Не вижу ничего гибкого. Валидация должна быть на стороне модели, а не во вьюшке. Тем более вся валидация — это выплюнуть варн в консоль. И никак не обработать. И работает только на дев-стейджинге. Какой в ней смысл? Никакого!

                                                      Вы же выносите метод в класс, используете его в соседнем методе.

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

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

                                                      Это ошибочное решение. Метод если занесете метод в переменную — рано или поздно обязательно кто-то вызовет такой метод без контекста и заделает баг. Методы в переменную не заносятся, а используются только с `this`. А в целом я не вижу смысла деструктуировать ВСЕ просто потому-что можно
                                                      • 0
                                                        Xуй 3нает
                                                        • 0
                                                          Мужик, ты всё знаешь. У тебя своё мнение. Пуленепробиваемое. Оставайся с ним. Если ты считаешь, что объявленный через const метод затрут, пусть будет так. Мне не жалко.

                                                          Переубеждать тебя не хочу. Не ходи в мои кейсы со своим говномётом. Ни к чему эта агрессия. ॐ
                                                          • –1
                                                            Это вы назвали мой код «лапшеподобным», а когда я его защитил и объяснил, почему такой написал — говорите, что у меня пуленепробиваемое мнение?

                                                            через const метод затрут

                                                            При чем тут const? Где я сказал слово «затрут»?

                                                            // первый пример:
                                                            const { method } = this;
                                                            return method();
                                                            
                                                            // второй пример:
                                                            return this.method();


                                                            Вы понимаете, что эти два примера работают по-разному и в первом возможны неприятные баги?
                                                            • +1
                                                              И правда я осёл, никаких затирашек не обнаружено. Речь была о потере контекста. Забрызган взор говном

                                                              Понял о каком баге идёт речь, вижу его очень часто. Выявляется молниеносно в момент написания. Метод переписывается на свойство со стрелочной функцией и всё встаёт на свои места.

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

                                                              ЗЫ ожидаю теперь комментария о том, что стрелочные функции — говно
                                                                
                                                                
                                                                
                                                                
                                                                
                                                                
                                                                
                                                              Не вижу ничего гибкого. Валидация должна быть на стороне модели, а не во вьюшке. Тем более вся валидация — это выплюнуть варн в консоль. И никак не обработать. И работает только на дев-стейджинге. Какой в ней смысл? Никакого!


                                                              И тем не менее мы работаем командами. Я в той, что пишет UI, есть те кто его использует и работает с API, есть те кто пишет API. Вот между первой и второй командой эти проптайпы приносят пользу, к продакшену всё должно быть многократно протестировано.
                                                              • +1
                                                                У вас прям костыль на костыле. Деструктуируем метод, а т.к. работать перестает — давай еще его стрелочным сделаем. Миленько. Непонятно, правда, зачем.

                                                                Понял о каком баге идёт речь, вижу его очень часто. Выявляется молниеносно в момент написания

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

                                                                ЗЫ ожидаю теперь комментария о том, что стрелочные функции — говно

                                                                Обратите внимание, я не называл ВСЁ говном, только ПропТайпы — ведь они совершенно бессмысленны и не нужны. А деструктуризация и стрелочные функции — хороши в меру.
                                                                • 0
                                                                  Постоянно вниз компонентам передаются методы, а там уже не будет никакого this.someMethod не использовать же bind. Стрелочные функции отлично с этим справляются. Теперь скорее .bind(this) — костыль

                                                                  И я уже объяснил где пригодяться propTypes. У нас разный рабочий поток. Моим компонентам передаются минимально необходимые параметры, внутренняя кухня не касается тех кто будет их использовать. А вот мне их читать и перечитывать предстоит скорее всего ещё не раз. В этом случае удобство чтения мной в приоритете.
                                                                  • –1
                                                                    Стрелочные функции отлично с этим справляются. Теперь скорее .bind(this) — костыль

                                                                    Вы второй раз за меня додумываете. Где я говорил, что необходимо использовать bind? Я же сказал, что стрелочные фукнкции хороши в меру, а не что надо использовать bind.
                                                                    • 0

                                                                      А как вам вот вариант из вот этого ответа: https://ru.stackoverflow.com/a/709112/178779? Решение проблемы или жуткий костыль? А то я сам пока сомневаюсь...

                                                                      • 0
                                                                        Сейчас этот костыль решают стрелочные функции.
                                                                        Достаточно изменить функцию так:

                                                                        class Foo {
                                                                            constructor(baz) {
                                                                                this._baz = baz;
                                                                            }
                                                                        
                                                                            bar = () => {
                                                                                 console.log(this._baz);
                                                                            }
                                                                        }
                                                                        
                                                                        var bar = new Foo(42).bar;
                                                                        bar(); // 42


                                                                        ЗЫ в TS не силён
                                                                        • 0
                                                                          Никаких дополнительных функций и телодвижений при этом не понадобится. Стрелочная функция будет с тем this в котором объявлена.
                                                                  • +1
                                                                    И тем не менее мы работаем командами. Я в той, что пишет UI, есть те кто его использует и работает с API, есть те кто пишет API. Вот между первой и второй командой эти проптайпы приносят пользу, к продакшену всё должно быть многократно протестировано.

                                                                    Значительно больше пользы принесла бы статическая типизация — вы бы могли организовать проверку не только по пути
                                                                    UsingApi => UI
                                                                    а по всему пути:
                                                                    Api => UsingApi => UI => UsingApi => Api

                                                                    А еще не только между слоями, но и внутри слоев. Ни одно, ни второе проп-тайп не позволяет.

                                                                    Видите, о чем я говорю? Из-за отвратительного инструмента вы покрываете от силы 20% проверками вместо 100%. Но из-за стокгольмского синдрома не способны заметить, что инструмент отвратительный и всеми силами его защищаете.
                                                                    • 0
                                                                      Уговорил сеньёра попробывать TS на следующем лендосе. Он раньше на AS писал. Ему тема близка.

                                                                      Текущий проект конечно и речи апрейдить нет, тут на React16 не могу протолкнуть обновление, не то, что смену стека. Так, что —
                                                                      что имеем то и защищаем, пока живу с prop-types
                                                                      • 0

                                                                        Сколько же у вас кода пишется для лендинг-страницы?


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

                                                                        • 0
                                                                          Понятно, что на маленьком проекте без мазы. Но пробовать сразу на серьёзном проекте как-то стрёмновато

                                                                          ЗЫ Для риторических вопросов подходит риторительный/вопрацательный знак — ‽

                                                                      • 0
                                                                        Системы типов

К несчастью, ложные заявления по поводу исследований и свидетельств не ограничиваются научно-популярными мемами. Они встречаются и в разработке ПО и оборудования. 
I think programmers who doubt that type systems help are basically the tech equivalent of an anti-vaxxer.

10:04 - 13 февр. 2015 г. · Hawaii, USA


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

Подобные вещи я наблюдаю не реже раза в неделю. Этот пример я выбрал не потому, что он особо вопиющий, но потому, что он типичный. Если читать твиттер некоторых ярых сторонников функционального программирования, можно периодически натыкаться на заявления о существовании серьёзных эмпирических свидетельств и всеобъемлющих исследований, поддерживающих эффективность систем типов.
                                • 0
                                  Но поскольку JavaScript соответствует спецификации ECMAScript, JavaScript является примером реализации ECMAScript.
                                  Получается, что ECMAScript основан на JavaScript, а JavaScript основан на ECMAScript.

                                  Причинно-следственные связи у автора не совсем корректно работают.

                                  расследование одной строкой:
                                  «Был JavaScript, под него написали спецификацию ECMA. „
                                  Это элементарно, Ватсон!
                                  Никаких споров о курице и яйце.

                                  Из спецификации ECMAScript вы узнаете, как создать скриптовый язык

                                  Из спецификации ECMAScript мы узнаем как создавался JavaScript и может написать расширения или модифицированный JavaScript, например ActionScript.
                                  • –1
                                    Говоря о поддержке в браузерах, обычно упоминают о «совместимости с ECMAScript», а не о «совместимости с JavaScript», хотя JavaScript-движки детально анализируют и выполняют… JavaScript.

                                    Нет. Люди в первую очередь говорят о «совместимости с JavaScript».

                                    Откуда пошла моду усложнять все? Придумывать какие то свои правила, давать определения уже существующим методам и впаривать их всем?
                                    Все эти плейсхолдеры, паттерны? Оно все было изобретено и продумано еще до рождения юнных стартаперов, которые это пропагандируют.
                                    Ощущение что цель это просто напустить интригу и завуалировать деятельность программистов.
                                    • –1
                                      Нет. Люди в первую очередь говорят о «совместимости с JavaScript».

                                      Говорить стоит о совместимости с версией JavaScript, которая выражается в номерах ECMAScript.


                                      Сейчас большинство браузеров полностью совместимы с ECMAScript 3.1 5, частично с ES6 ES2015.
                                      ES3 код должен работать корректно во всех браузерах с начала второго тысячелетия


                                      Подробнее об этом рассказано в этом цикле статей → Как появился Mocha/LiveScript, позже переименованный в JavaScript.

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

                                    Самое читаемое