Движок JavaScript — это программа, которая читает ваш исходный код и превращает его в действия процессора. Именно движок, а не «интерпретатор из Блокнота», отвечает за то, как исполняется JavaScript. Ниже разберу, что происходит с кодом от файла до машинных инструкций на примере V8 (движок Chrome и Node.js), чем интерпретатор отличается от JIT-компилятора, почему язык называют интерпретируемым и как запустить JS прямо сейчас в REPL и онлайн-песочнице.
Содержание
Сразу разведу три вещи, которые легко путают: язык (спецификация ECMAScript описывает синтаксис и семантику), движок (V8, SpiderMonkey, JavaScriptCore — исполняет код по этой спецификации) и среда выполнения (браузер или Node.js — дает движку API вроде DOM, файлов и таймеров). Спецификация не требует ни интерпретации, ни компиляции — это решает конкретный движок.
Почему JavaScript называют интерпретируемым
Ярлык «интерпретируемый» относится к реализации и к рабочему процессу, а не к самому языку. Исторически первые движки просто интерпретировали код построчно, и для разработчика это выглядит так до сих пор: нет отдельного шага сборки, вы отдаете движку исходный текст, а не заранее скомпилированный бинарник. В этом смысле рабочий цикл ближе к Python, чем к C++.
Но внутри современный движок давно не «чистый интерпретатор». V8 компилирует горячие участки в машинный код на лету. То есть JavaScript — интерпретируемый по способу поставки кода и по отсутствию AOT-сборки, но частично компилируемый по внутреннему механизму исполнения. Называть его «просто интерпретируемым» — упрощение; граница именно в этом.
Отсюда и путаница в старых статьях со словами «компилятор JavaScript» про Notepad++ или Sublime Text. Это текстовые редакторы, а не компиляторы: они подсвечивают синтаксис и дополняют код, но сами JS не исполняют. Исполнением занимается движок внутри браузера или Node.js.
Интерпретатор, компилятор и JIT — в чем разница
Три подхода отвечают на один вопрос по-разному: когда исходный код превращается в машинные инструкции.
| Подход | Когда переводит в машинный код | Плюс | Минус |
|---|---|---|---|
| Интерпретатор | По ходу выполнения, инструкция за инструкцией | Мгновенный старт, не нужна сборка | Медленный на повторяющихся участках |
| Компилятор (AOT) | Заранее, до запуска, целиком | Быстрое выполнение готового бинарника | Нужен шаг сборки, нет мгновенного старта |
| JIT (just-in-time) | Во время выполнения, только для горячих участков | Быстрый старт и высокая скорость на горячем коде | Расход памяти и CPU на компиляцию, возможна деоптимизация |
Движки JavaScript используют гибрид: интерпретатор для мгновенного старта плюс JIT-компиляция того кода, который выполняется часто. Так вы не ждете сборку, но и не платите скоростью на «горячих» функциях.
Как V8 исполняет код: от исходника до машинного кода
V8 — открытый движок Google, написанный на C++. Он стоит в Chrome, Edge, Opera, а также в серверных средах Node.js 24 LTS и Deno. Путь кода внутри выглядит так:
- Парсинг. Движок читает текст и строит AST — дерево, которое описывает структуру программы (функции, выражения, циклы).
- Генерация байткода. Компонент Ignition превращает AST в компактный байткод и сразу его исполняет. Это и есть интерпретатор V8 — он дает мгновенный старт без ожидания компиляции.
- Тиринг (постепенная оптимизация). V8 считает, как часто вызывается функция. «Горячий» код передается оптимизирующим компиляторам, которые переводят байткод в машинный код под конкретный процессор.
- Деоптимизация. Оптимизации строятся на предположениях о типах данных. Если предположение ломается (например, в функцию, всегда работавшую с числами, вдруг пришла строка), V8 откатывает функцию обратно на байткод и при необходимости оптимизирует заново.
Оптимизация в V8 многоуровневая. Ориентировочная схема компонентов на 2026 год:
| Компонент V8 | Роль | Что делает |
|---|---|---|
| Ignition | Интерпретатор | Генерирует и исполняет байткод, быстрый старт |
| Sparkplug | Базовый компилятор | Быстро переводит байткод в машинный код без тяжелых оптимизаций |
| Maglev | Оптимизирующий компилятор среднего уровня | Умеренно оптимизирует горячие функции с небольшой задержкой |
| TurboFan | Оптимизирующий компилятор верхнего уровня | Агрессивно оптимизирует самый горячий код |
Набор и порядок уровней зависят от версии V8, поэтому конкретные названия стоит сверять с текущим релизом (см. точки для фактчека). Ключевой принцип устойчив: чем чаще исполняется код, тем сильнее движок вкладывается в его оптимизацию.
Проследить тиринг можно флагами Node.js. Они показывают, какие функции оптимизируются и деоптимизируются:
node --trace-opt --trace-deopt hot.js
Точный формат вывода этих флагов меняется между версиями, но общий эффект один: часто вызываемая функция появится в логе как оптимизированная.
Минимальный пример: горячая функция
Сохраните файл hot.js и запустите его через node hot.js. Функция sum сначала исполняется байткодом Ignition, а после множества вызовов V8 переведет ее в машинный код.
function sum(n) {
let acc = 0;
for (let i = 0; i < n; i++) {
acc += i;
}
return acc;
}
// первый вызов: код исполняет интерпретатор Ignition
console.log(sum(1000000)); // выведет 499999500000
// прогреваем функцию: после многих вызовов V8 оптимизирует sum
let last = 0;
for (let k = 0; k < 200; k++) {
last = sum(1000000);
}
console.log(last); // снова 499999500000, но теперь это машинный код
В консоли обе строки дадут одно число:
499999500000
499999500000
Результат не меняется — меняется скорость. Первый вызов идет через интерпретатор, а повторяющийся цикл к концу прогона исполняется уже скомпилированным машинным кодом. Именно поэтому «разогретый» бенчмарк на JavaScript почти всегда быстрее первого запуска.
Движки в браузерах и Node.js
V8 — не единственный движок. У каждого крупного браузера свой, и все они реализуют один стандарт ECMAScript, поэтому один и тот же код работает везде.
| Движок | Где стоит | Разработчик |
|---|---|---|
| V8 | Chrome, Edge, Opera, Node.js, Deno | |
| SpiderMonkey | Firefox | Mozilla |
| JavaScriptCore (Nitro) | Safari | Apple |
Важно не путать движок и среду выполнения. Движок исполняет JavaScript. Среда выполнения (runtime) добавляет вокруг него внешний мир: в браузере это DOM, fetch и события, в Node.js 24 — модули, доступ к файловой системе, сеть и цикл событий поверх того же V8. Один движок, разные среды — поэтому document.querySelector работает в браузере, но не в Node.js, а fs.readFile — наоборот.
Как запустить JavaScript прямо сейчас
Для эксперимента не нужен ни компилятор, ни сборка. Есть три быстрых способа.
1. Браузерная консоль. Откройте инструменты разработчика (F12 или Ctrl+Shift+I, в Safari сначала включите меню разработчика), вкладку Console, впишите строку и нажмите Enter:
[1, 2, 3, 4].filter(x => x % 2 === 0);
Консоль сразу покажет результат вычисления:
(2) [2, 4]
Это REPL — read-eval-print loop: движок читает выражение, вычисляет, печатает результат и ждет следующее. Удобно для проверки одной строки без файла.
2. REPL в Node.js. Установите Node.js 24 LTS и в терминале наберите node без имени файла — откроется интерактивная сессия:
$ node
Welcome to Node.js v24.x.x.
> 2 + 2
4
> const name = "otus"
undefined
> name.toUpperCase()
'OTUS'
> .exit
Здесь undefined после const name = "otus" — это нормально: объявление переменной не возвращает значения, REPL честно печатает undefined. Команда .exit (или Ctrl+D) закрывает сессию.
3. Онлайн-песочница. Если ставить Node.js не хочется, подойдут браузерные редакторы (песочницы) — CodePen, JSFiddle, PlayCode, Replit и подобные. Открываете страницу, пишете код в поле, видите вывод рядом. Под капотом это тот же движок браузера, просто с готовым интерфейсом. Для первых шагов этого достаточно; для реальных проектов лучше локальные Node.js плюс редактор кода, например VS Code или WebStorm.
Ошибку в любом из этих способов движок покажет сразу. Например, обращение к необъявленной переменной:
console.log(counter);
даст в консоли не число, а исключение:
ReferenceError: counter is not defined
Исправление — объявить переменную до использования:
let counter = 0;
console.log(counter); // 0
Выводы
- JavaScript исполняет движок (V8, SpiderMonkey, JavaScriptCore), а не текстовый редактор; редакторы лишь помогают писать код.
- «Интерпретируемый» — это про реализацию и рабочий цикл (нет AOT-сборки), а не про язык: внутри V8 горячий код компилируется в машинный.
- V8 стартует через интерпретатор байткода Ignition, а часто вызываемые функции оптимизирует JIT-компиляторами (Sparkplug, Maglev, TurboFan) и при смене типов деоптимизирует.
- Движок и среда выполнения — разные вещи: движок исполняет JS, а браузер или Node.js 24 дают ему API (DOM, файлы, сеть).
- Запустить JavaScript можно за секунды — в консоли браузера, в REPL Node.js или в онлайн-песочнице.
Где применяется / связь с практикой
Понимание того, как движок исполняет код, — это не теория ради теории. Оно объясняет, почему стоит держать в функции стабильные типы данных (иначе V8 деоптимизирует ее), почему первый прогон медленнее прогретого и почему один и тот же код по-разному ведет себя в браузере и в Node.js. Эти вещи всплывают на любом собеседовании фронтендера и в первый же месяц реальной работы.
Освойте тему на практике
Системно освоить сам язык — переменные, функции, типы, работу с массивами и объектами — помогает курс «JavaScript Basic» в Otus: с практикой в REPL и разбором того, как код превращается в результат. Посмотреть формат и темы вживую можно на бесплатных открытых уроках Otus — там же отвечают на вопросы по старту в веб-разработке.
FAQ
JavaScript компилируется или интерпретируется?
И то, и другое. Разработчик отдает исходный код без шага сборки (как у интерпретируемых языков), но внутри движок JIT-компилирует горячие участки в машинный код. Чистого разделения тут нет.
Чем движок отличается от среды выполнения?
Движок (V8) исполняет сам JavaScript. Среда выполнения (браузер, Node.js) добавляет вокруг него API: DOM и fetch в браузере, файлы и сеть в Node.js. Поэтому не весь код работает в обеих средах.
Что быстрее для запуска кода — онлайн-песочница или Node.js?
Для одной проверки быстрее консоль браузера или онлайн-песочница: ничего ставить не нужно. Для проектов с файлами, зависимостями и отладкой удобнее локальный Node.js с редактором кода.



