Javascript является неотъемлемой частью современной веб-разработки. В этой теоретической статье мы рассмотрим, что такое Javascript Engine, что такое Javascript Runtime Environment и как код Javascript выполняется под капотом.
Javascript Engine — это программа, отвечающая за выполнение кода JS. Это часть среды выполнения JavaScript. Подождите, что, черт возьми, такое среда выполнения JavaScript?
Среда выполнения Javascript — это своего рода коробка, в которой код JavaScript действительно работает. Он обеспечивает доступ к внешнему миру, например, к DOM (в случае браузеров) или файловой системе (в случае Node), и это лишь некоторые из них. Если у нас нет Javascript Runtime Environment, мы не сможем использовать setTimeout, console или другие методы API, предоставляемые внешним миром.
В типичном веб-браузере среда выполнения Javascript состоит из:
- JS-движок
- Веб-API
- Очередь обратного вызова, также известная как Очередь заданий, также известная как Очередь задач макросов
- Цикл событий
В этом блоге мы рассмотрим только JS Engine.
Все браузеры имеют свой движок JS. Google Chrome имеет V8. У Mozilla есть Spider Monkey, и этот список можно продолжить. JS Engine в основном преобразует код высокого уровня (то, что мы пишем) в код машинного уровня (то, что понимают компьютеры).
Прежде чем мы углубимся и выясним, что происходит в процессе, нам нужно знать две очень важные вещи: компилятор и интерпретатор.
Компилятор: он берет исходный код и сначала компилирует его построчно, прежде чем даже выполнить одну строку кода. Компилятор компилирует код в высокооптимизированный машинный код и одновременно проверяет наличие синтаксических или семантических ошибок. После компиляции генерируется файл, содержащий понятный машине низкоуровневый код. Используется в C++ (помните файл .exe из старых добрых студенческих дней?).
Интерпретатор: берет исходный код и сразу же начинает выполнять его построчно.
Итак, теперь вы можете спросить, является ли Javascript компилируемым или интерпретируемым языком.
Что ж, это лучшее из обоих миров. Вот как:
По сути, выполнение кода состоит из трех этапов:
1. Анализ
2. Выполнение
3. Компиляция
Синтаксический анализ. Механизм JS берет исходный код, разбивает его на токены и создает структуру данных под названием Абстрактное синтаксическое дерево (AST). Если в программе есть синтаксическая ошибка, выполнение здесь останавливается, и управление возвращается.
Выполнение: этот сгенерированный AST передается в интерпретатор, который генерирует байт-код и начинает выполнение кода построчно. При выполнении байт-кода интерпретатор собирает данные профилирования, которые можно использовать позже для ускорения выполнения. Данные профилирования содержат код, который можно оптимизировать. Например, функция вызывается несколько раз.
Компиляция: сгенерированный байт-код и данные профилирования передаются так называемому оптимизирующему компилятору, который создает высокооптимизированный и эффективный машинный код (на основе данных профилирования), который работает очень быстро. Этот оптимизированный код заменяет неоптимизированный код, сгенерированный интерпретатором, и постепенно Javascript Engine становится горячим, а выполнение кода улучшается.
Таким образом, Javascript использует как интерпретатор, так и компилятор, а также компиляцию JIT (Just-in-time).
Это все на сегодня.