Автор: Лидия Холли.
Переводчик: Front-end Xiaozhi
Источник: разработчик
Ставьте лайк и смотрите снова, формируйте привычку
эта статьяГитхаб:GitHub.com/QQ449245884…Он был включен в вышеизложенное, и более ранние статьи с высокими похвалами были классифицированы, а также было систематизировано множество моих документов и учебных материалов. Добро пожаловать в Star and Perfect. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Надеюсь, у нас что-то получится вместе.
JavaScript — это круто, но как движок JS понимает код, который мы пишем?Как разработчикам JS, нам обычно не нужно самим иметь дело с компилятором. Тем не менее, знание основ движка JS и понимание того, как он обрабатывает код JS и преобразует его во что-то, понятное машине, определенно полезно.
Уведомление: эта статья в основном основана на движке V8, используемом браузерами Node.js и Chrome.
Анализатор HTML сталкивается с исходным кодомscript
Этикетка. Код из этого источника загружается из сети, кеша или установленных сервис-воркеров. Ответом является отправка запрошенного сценария в виде потока байтов, за который отвечает декодер потока байтов. Декодер потока байтов декодирует поток байтов по мере его загрузки.
Декодер потока байтов создается из декодированного потока байтов.жетон. Например,0066
декодируется вf
, 0075
прибытьu
, 006e
прибытьn
, 0063
прибытьc
, 0074
прибытьt
, 0069
прибытьi
, 006f
прибытьo
, 006e
прибытьn
, за которым следует пробел. как в JSfunction
, которое является зарезервированным ключевым словом в JS, создает токен и отправляет его парсеру. То же самое верно и для остальной части потока байтов.
Движок использует два парсера:Препарсер (препарсер)а такжеПарсер (парсер). Препарсер просто заранее проверяет токены на наличие синтаксических ошибок. Это сокращает время, необходимое для поиска ошибок в вашем коде, которые в противном случае синтаксический анализатор нашел бы позже.
Если ошибок нет, парсер создаст узлы из токенов, полученных от декодера потока байтов. Используя эти узлы, он создает абстрактное синтаксическое дерево, т.е.AST.
Далее твоя очередьустный переводчик. траверсASTи согласноASTСодержит информацию для интерпретатора, генерирующего байт-код. Как только байт-код будет полностью сгенерирован,ASTбудут удалены, тем самым освободив место в памяти. Наконец, сгенерированный машинный код можно запустить на компьютере.
Хотя байт-код быстрый, он может быть быстрее. При запуске этого байт-кода будет сгенерирована информация. Он может определить, часто ли происходит определенное поведение, и тип используемых данных. Возможно, функция вызывалась десятки раз: пришло время оптимизировать ее, чтобы она работала быстрее!
Байт-код отправляется вместе с сгенерированным отзывом о типе наОптимизирующий компилятор. Оптимизирующий компилятор получает информацию о байт-коде и типе и генерирует оптимизированный машинный код на основе этой информации.
JS — это язык с динамической типизацией, что означает, что типы данных могут постоянно меняться. Если бы движку JS приходилось каждый раз проверять тип данных значения, это было бы очень медленно.
Вместо этого JS-движки используют технику, называемую встроенным кэшированием. Он кэширует код в памяти в надежде, что в будущем он вернет то же значение с тем же поведением.Допустим, вызывается какая-то функция100
раз и до сих пор всегда возвращает одно и то же значение. это будет предполагать101
Это значение также возвращается при следующем вызове.
Предположим, у нас есть следующая функцияsum
, который (пока что) вызывается каждый раз с числовым значением в качестве аргумента:
function sum(a, b) {
return a + b
}
sum(1,2)
Результат выполнения3
. В следующий раз, когда он будет вызван, он будет считать, что мы звоним ему снова с теми же двумя номерами.
Если приведение ложно, то динамический поиск не требуется, только результат сохраняется в определенном слоте памяти, на который уже есть ссылка. В противном случае, если предположение неверно, он деоптимизирует код и вернется к исходному байт-коду, а не к оптимизированному машинному коду.
Например, при следующем вызове мы передаем строку вместо числа. Поскольку JS динамически типизируется, в этом нет ничего плохого.
function sum(a, b) {
return a + b
}
sum('1',2)
это означает числа2
будет приведен к строке, и функция вернет строку'12'
. Он возвращает байт-код, который выполняет интерпретацию и обновляет обратную связь о типе.
Надеюсь, эта статья будет вам полезна!Конечно, есть и другие части движка (куча JS, стек вызовов и т. д.), которые не были освещены в этой статье, и ими мы продолжим делиться позже. Если вас интересует внутреннее устройство JS, я настоятельно рекомендую провести небольшое исследование самостоятельно, V8 имеет открытый исходный код и содержит отличную документацию о том, как он работает.
Ошибки, которые могут существовать после развертывания кода, не могут быть известны в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку журнала.Кстати, я рекомендую всем полезный инструмент мониторинга ошибок.Fundebug.
общаться с
Статьи из серии галантерейных товаров резюмируются следующим образом: если вы чувствуете себя хорошо, нажмите «Звезда», добро пожаловать в группу, чтобы учиться друг у друга.
Я Сяо Чжи, автор официального аккаунта "Moving the World",Продолжайте знакомить энтузиастов с передовыми технологиями. Я буду часто делиться тем, что я узнал и увидел, На пути продвижения, давайте подбадривать друг друга!
Обратите внимание на публичный аккаунт и отвечайте в фоновом режимеБлагосостояние, вы можете увидеть преимущества, вы знаете.