От автора: в этой статье я расскажу о некоторых важных аспектах JavaScript и его экосистемы, которые должны знать и понимать профессиональные опытные разработчики JavaScript.
О языке JavaScript
Как и в случае большинства языков программирования, у нас есть несколько версий языка. Язык, новые функции и будущее определяются техническим комитетом, который называется TC-39.
Существует два соглашения об именах для ссылки на версию JavaScript. Первый — ES6, это короткая версия. Она подразумевает произвольную версию (v5, v6, v7, …). Также у нас есть такое соглашение об именах, как ES2016, которое скорее подразумевает год, когда была опубликована версия. ES относится к «EcmaScript». Чтобы привести пример:
ES6 невероятно похож на ES2015
ES7 невероятно похож на ES2016
И так далее…
ESNEXT относится к следующей версии и соответствующим предложениям.
Таким образом, язык и версия определяют собственные ключевые слова, функции и собственные методы, доступные вам как разработчику (упрощенное определение). Мой любимый ресурс относительно JavaScript — MDN.
Философия TC-39 заключается в том, чтобы JavaScript всегда был обратно совместим. Язык изменяется на основе предложений, которые могут быть внесены кем-либо, если предложение получит поддержку, оно перейдет с этапа 0 (идея) на этапы 1 (предложение), этап 2 (черновик) и этап 3 ( кандидат).
После того, как предложение прошло все этапы, TC-39 в конечном итоге отклоняет или принимает предложение и добавляет его в спецификацию ECMAScript.
На самом деле, JavaScript — это просто реализация спецификации ECMAScript, это означает, что существуют другие реализации этой спецификации (например, ActionScript, JScript,…), но эта статья посвящена JavaScript.
Если вы работаете в NodeJS, используйте Node.green, чтобы узнать, какие функции JavaScript поддерживаются используемой версией NodeJS.
Движок JavaScript
Теперь мы знаем, что у нас есть язык JavaScript, другая версия и как он развивается со временем. Но это только сам язык, нам нужно какое-то приложение, которое фактически читает, интерпретирует и выполняет код JavaScript, который мы пишем.
Движок JavaScript — приложение , которое отвечает за это. Движок — это реальное место, где код JavaScript оживает и воплощается в жизнь. Движок также заботится об управлении памятью и сборке мусора. В мире есть несколько движков JavaScript:
V8: Создан Google
SpiderMonkey: Создан Mozilla
JavaScriptCore: Создан Apple
Chakra: Создан Microsoft
Итак, почему мы обращаем внимание движкам JavaScript? Ну, по двум причинам, которые я могу придумать:
Поддержка версий. TC-39 может решить, какие новые функции мы добавим в JavaScript, и вы можете решить, в какой версии ES вы хотите написать свой код, но это зависит от движка. Поэтому, как только появится новая функция JS, вам все равно нужно убедиться, что движок, на котором она работает, поддерживает ее.
Производительность. Когда мы хотим поговорить о производительности в JavaScript, мы можем часами спорить о «логической» производительности (например, имеет ли мой алгоритм сложность O (1) или O (N)). Но это также сводится к тому, насколько эффективен движок. Движок может выполнить много магии под капотом, чтобы повысить производительность, даже для неэффективного кода. Таким образом, конечная производительность может действительно отличаться для одного и того же фрагмента кода на разных движках. Кроме того, производительность может отличаться для разных версий одного и того же движка.
Обратите внимание, что мы говорим о «движке», а не о браузере или чем-то в этом роде. Дело в том, что браузер использует движок JavaScript для выполнения JavaScript, так как он также может использовать выделенный движок для рендеринга HTML и CSS. Запомните, что браузер делает гораздо больше, чем просто выполняет JavaScript (не выгружает его в движок JS).
Движок имеет свои собственные версии, новая версия движка может принести улучшения производительности и / или поддержку новых функций ES.
Клиентский и серверный JavaScript
Мы можем запустить JavaScript в браузере (например, Chrome) или на сервере (например, NodeJS). Как и в браузере, javascript на стороне сервера также выполняется движком JavaScript. NodeJS использует V8, тот же движок, что и Chrome.
Один и несколько потоков
JavaScript является однопоточным и использует цикл обработки событий. В документах NodeJS вы можете найти действительно глубокое объяснение. Это означает, что в любой момент может быть выполнен только один фрагмент кода. Вы можете иметь параллельные вещи, но не параллельно. Четный дизайн цикла обеспечивает это, так что вы не можете иметь 2 функции в цикле событий, выполняющихся параллельно.
Так что да, JavaScript является строго однопоточным языком, но означает ли это, что многопоточность вообще не используется? Возможно! Но это абстрагируется от всего дизайна Цикла событий. Когда я запускаю 5 веб-запросов, асинхронно читаю 2 файла и 10 запросов к БД, эти действия ввода-вывода передаются движку JavaScript, который передает их ОС. После этого ОС может решить (если возможно) использовать многопоточность. Это то, что вас, как разработчика JavaScript, не должно волновать, это выходит за рамки вашей компетенции, вы не имеете над этим никакого контроля, и вам также не следует заботиться об этом.
Проще говоря, сам код JavaScript является однопоточным, а ввод/вывод — это один большой черный ящик, который вас не волнует.
Веб API
В прошлом вы могли использовать такие веб API, как «GeoLocation», «Fetch», «Gamepad» или, что более вероятно, «Document». Это API, которые являются интерфейсом вашего браузера. Вашего браузера, запомните это. Браузер отвечает за то, чтобы эти API существовали в глобальной области видимости.
Когда вы делаете что-то подобное document.getElementById(), браузер делает методы documentобъект и getElementById() доступными для вас, потому что вы взаимодействуете с частями веб-страницы или браузера (например, когда вы используете navigation.userAgent). Браузер также отвечает за реализацию.
Причина, по которой я указываю на это, заключается в том, что это WEB API. Это значит, что эти API доступны только тогда, когда ваш код JavaScript выполняется в браузере, а не на сервере, как в случае с NodeJS. Это может быть очевидно для многих разработчиков, но для начинающего разработчика JS это очень важное различие. Вот почему объект document не существует, когда вы выполняете свой код в NodeJS, потому что код не выполняется в браузере.
Некоторые из веб API имитируются в NodeJS, и хорошим примером этого является console.log() API. Но реализация сильно отличается, в браузере console.log() будет выводиться в консоли разработчика, в NodeJS это будет выводиться по умолчанию в stdout.
Поэтому, когда вы видите, что что-то берется из воздуха, например, console.log() или document.getElementById(), когда вы явно не импортировали эти объекты или методы (например, import console from ‘console’ или const console = require(‘console’)), вы, скорее всего, работали с API, который был включен средой выполнения, например, браузером или NodeJS. Это не сделано движком.
Примечание: Движок может также сам (но это редко) ввести некоторые API для себя, примером может служить Error.captureStackTraceна V8. Само собой разумеется, что эта функция не будет существовать, если вы запустите ее в другом движке JavaScript.
Транспиляция
Мы знаем, что есть несколько версий JavaScript, несколько браузеров, несколько движков JavaScript, имеющих также свои собственные версии. Сколько сложностей, когда вы просто хотите написать JavaScript.
При работе в NodeJS ваша среда довольно статична. Вы решаете, какая версия NodeJS запущена, что также определяет, какой тип и версию движка вы используете. Хотите использовать более новую версию JavaScript? Обновите версию NodeJs, без проблем (кроме нескольких возможных сложностей). Я имею в виду, что вам не нужно заботиться ни о чем, кроме одной замкнутой среды.
Этот сценарий мечты не существует в браузере. Все ваши пользователи могут использовать разные браузеры (и разные версии), которые имеют разные движки JavaScript (и снова их разные версии).
Легко было бы сказать всем пользователям, чтобы они обновляли браузер до последней версии, но не у всех есть разные ноу-хау для этого или права доступа (корпоративные ограничения). Так как же использовать новую версию JavaScript, не нарушая при этом веб-приложение? Транспиляция!
Транспиляция обычно определяется как «перенос исходного кода с одного языка высокого порядка в исходный код на другом языке высокого порядка». Для браузера мы делаем почти то же самое, но вместо этого мы «переносим исходный код более новой версии JavaScript на более старую версию JavaScript».
Поскольку большинство браузеров поддерживают ES5, так как он очень старый, сообщество разработало эту концепцию, переведя код JavaScript ES7 в код, совместимый с ES5. Вы пишете свой код в ES7, переносите его и используете перенесенную версию ES5 своего приложения для обслуживания всех пользователей. Отлично, правда?
Самый распространенный «транспиллер» для JavaScript — это Babel. У них есть онлайн-инструмент, в котором вы можете увидеть транслируемую версию любого введенного вами кода.
Если вы хотите проверить, какой браузер поддерживает что, и не только JavaScript, но также CSS и HTML, обратитесь к caniuse.com. Я надеюсь, что вы узнали что-то новое из этого поста.
Автор: Ian Segers
Источник: https://itnext.io
Редакция: Команда webformyself.