Демистификация движка JavaScript

V8

- Углубленный взгляд на самые популярные сегодня языки разработки

Оригинальная ссылка:JavaScript: Under the Hood

предисловие

Первоначально JavaScript мог работать только в веб-браузерах, но с появлением Node JavaScript теперь может работать и на стороне сервера. Хотя мы можем знать, когда и где его использовать, действительно ли мы понимаем, что происходит за выполнением этих сценариев?

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

JavaScript — это язык высокого уровня, но, в конце концов, компьютер может понять только1 и 0. Так как же код, который мы пишем, понимает компьютер? Освоение основ языка программирования, который вы изучаете, позволит вам писать более качественный код. В этой статье мы рассмотрим только один вопрос:Как работает JavaScript?

А теперь к делу~

JavaScript-движок

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

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

  • Chakra, Microsoft IE/Edge
  • SpiderMonkey, FireFox
  • V8, Chrome

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

Внутри движка JavaScript

Мы уже знаем, что двигатель необходим, поэтому у нас может возникнуть соблазн подумать:

Кто изобрел движок JavaScript?

Ответ: любой может. Это просто инструмент для анализа нашего кода и перевода его на другой язык.V8является одним из самых популярных движков JavaScript иChromeа такжеNodeJSдвигатель б/у. Он написан на C++, языке низкого уровня. Но если каждый создаст движок, сцена выйдет из-под контроля.

Поэтому, чтобы установить спецификацию для этих двигателей,ECMAТак родился стандарт, который в основном предоставляет спецификацию того, как писать движок и все функции JavaScript. Вот почему новые функции реализованы на ECMAScript 6, 7, 8. В то же время движок также был обновлен для поддержки этих новых функций. Таким образом, мы смогли проверить наличие расширенных функций JS в браузере во время разработки.

Ниже мы подробно рассмотрим двигатель V8, поскольку основные концепции одинаковы для всех двигателей.

JavaScript V8 Engine

На картинке выше показан внутренний рабочий процесс JS Engine. Код, который мы вводим, пройдет следующие этапы:

  1. Parser
  2. AST
  3. Интерпретатор генерирует ByteCode
  4. Profiler
  5. Компилятор генерирует оптимизированный код

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

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

Interpreter VS Compiler

Как правило, существует два способа преобразования кода в машиночитаемый язык. Концепции, которые мы собираемся обсудить, применимы не только к JavaScript, но и к большинству языков программирования, таких как Python, Java и т. д.

  • InterpreterПрочитайте код построчно и немедленно выполните его.
  • CompilerПрочтите весь свой код, выполните некоторые оптимизации и сгенерируйте оптимизированный код.

Давайте посмотрим на следующий пример.

function add(a, b) {
    return a+b
}
for(let i = 0; i < 1000; i++) {
    add(1 + 1)
}

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

  1. InterpreterПосле получения приведенного выше кода он будет читать строку за строкой и немедленно выполнять код до конца цикла. Его задача — просто перевести код в то, что наши компьютеры смогут понять в режиме реального времени.
  2. Если этот получатель кодаCompiler, он сначала полностью прочитает всю программу, проанализирует код, который мы хотим выполнить, и сгенерирует машинный язык, понятный компьютеру. процесс как получениеX(наш js-файл) и сгенерироватьY(машинный язык)Такой же.如果我们使用 Interpreter 执行Y, затем получить и выполнитьXТот же результат.

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

  • InterpreterПреобразуйте исходный код в эквивалентный машинный код построчно.
  • CompilerПреобразуйте весь исходный код в машинный код с самого начала.

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

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

Плюсы и минусы интерпретатора и компилятора

  • InterpreterПреимущество в том, что код можно выполнить сразу, не дожидаясь компиляции. Это очень удобно для запуска JS в браузере, потому что все пользователи не хотят тратить время на ожидание компиляции кода. Однако он работает медленнее, когда нужно выполнить много JS-кода. Помните тот небольшой фрагмент кода из приведенного выше примера? В коде выполняется 1000 вызовов функций. Функция add вызывается 1000 раз, но ее вывод остается прежним. Но Interpreter по-прежнему выполняется построчно, что будет медленнее.
  • В той же ситуации,CompilerНекоторых оптимизаций можно добиться, заменив цикл на 2 (поскольку функция добавления каждый раз выполняет 1 + 1). Оптимизированный код, полученный компилятором, может быть выполнен за более короткое время.

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

Хорошо, у нас есть необходимые знания об интерпретаторе и компиляторе. Теперь вернемся к теме — движку JS.

Итак, учитывая плюсы и минусы компиляторов и интерпретаторов, что, если мы воспользуемся преимуществами обоих? ЭтоJIT(Just In Time)Где появляется компилятор. Это комбинация интерпретатора и компилятора, и большинство браузеров теперь реализуют это быстрее и эффективнее. В то же время двигатель V8 также использует эту функцию.

JavaScript V8 Engine

Во время этого процесса

  1. Parser— это синтаксический анализатор, который идентифицирует, анализирует и классифицирует части программы по различным ключевым словам JavaScript. Он может различать, является ли код методом или переменной.
  2. Потом,AST (абстрактное синтаксическое дерево)Подобная древовидной структуру построена на основе классификации парсера. ты можешь использовать этоAST ExplorerПосмотрите на структуру дерева.
  3. Затем AST предоставляетсяInterpreterСгенерировать байт-код. Как было сказано выше, ByteCode не является кодом самого низкого уровня, но его можно выполнить. На этом этапе браузер выполняет ByteCode с помощью движка V8, чтобы выполнить работу, поэтому пользователю не нужно ждать.
  4. в то же время,Profilerбудет искать код, который можно оптимизировать, и передавать егоCompiler. Пока Компилятор генерирует оптимизированный код, браузер временно выполняет операции с ByteCode. И как только компилятор сгенерирует оптимизированный код, оптимизированный код полностью заменит временный байт-код.
  5. Таким образом, мы можем в полной мере воспользоваться преимуществами интерпретатора и компилятора. Пока интерпретатор выполняет код, профилировщик ищет код, который можно оптимизировать, а компилятор создает оптимизированный код. Затем замените код ByteCode оптимизированным кодом более низкого уровня, например машинным кодом.

Это просто означает, что производительность будет постепенно улучшаться, не блокируя время выполнения.

О байт-коде

Как машинный код, ByteCode не может быть понят и выполнен всеми компьютерами. еще должно быть каквиртуальная машинаили нравитсяДвижок Javascript V8Такое промежуточное ПО может перевести его на машиночитаемый язык. Вот почему наш браузер может выполнять ByteCode в интерпретаторе с помощью движка JavaScript на вышеуказанных 5 этапах.

Так что у вас может быть другой вопрос,

Является ли JavaScript интерпретируемым языком?

JavaScript является интерпретируемым языком, но не полностью.Brendan EichПервоначально создал движок JavaScript на ранних стадиях JavaScript."Обезьяна-паук"из. У движка есть интерпретатор, который сообщает браузеру, как выполнять код. Но теперь наш движок включает в себя не только Интерпретатор, но и Компилятор. Наш код можно не только преобразовать в ByteCode, но и скомпилировать для вывода оптимизированного кода. Так что технически все зависит от того, как реализован движок.

Так работает весь движок JavaScript. Я считаю, что вы можете понять это, не изучая JavaScript. Конечно, вы даже можете писать код, не зная, как работает JavaScript. Однако, если мы поймем некоторые закулисные знания, это может позволить нам писать лучший код.

Добро пожаловать на перепечатку, не забудьте указать автора и источник~~