Javascript — самая большая тенденция в наши дни. Его экосистема усложнилась и будет продолжать усложняться. Итак, разработчикам javascript важно знать о внутренностях Javascript, чтобы использовать его лучше и эффективнее.
Javascript — это однопоточный язык программирования. Это означает, что выполнение кода выполняется последовательно, любой код, выполнение которого занимает больше времени, блокирует все, что необходимо выполнить.
Как я уже сказал, Javascript является однопоточным, поэтому этот язык может столкнуться с проблемами взаимодействия с пользователем, когда браузер хочет отправить HTTP-запрос или загрузить изображение, вызвать событие DOM. Будет ли браузер зависать до тех пор, пока этот запрос не будет разрешен? Если он замерзнет, это плохая сторона, верно?
Следовательно, важно понимать, что запуск любого веб-приложения на самом деле включает набор технологий, таких как JavaScript Engine (например, Chrome's V8 , SpiderMonkey от Mozilla, JavaScriptCore от Safari), набор веб-API (например, DOM, AJAX), Event Loop и Очередь обратного вызова. Очередь обратного вызова также известна как очередь событий. Следовательно, весь этот сценарий представляет собой Javascript Runtime.
Чтобы визуализировать, как JavaScript выполняет программу, нам нужно понять о среде выполнения JavaScript. Давайте сначала узнаем о компонентах, а затем опишем весь сценарий.
Стек вызовов. Это структура данных, которая записывает вызовы функций, в основном, где в программе мы находимся. Если мы вызываем функцию для выполнения, мы помещаем что-то в стек, а когда мы возвращаемся из функции, мы сталкиваемся с вершиной стека.
Давайте лучше поймем стек вызовов на примере изображения.
Когда браузер впервые загружает ваш скрипт, он входит в Global Execution Context
по умолчанию. При каждой записи состояние стека также называется кадром стека.
Здесь первая запись в стеке — foo(). fooфункция вызывает bar(), поэтому второй элемент стека — bar(). И функция bar вызывает baz(), поэтому третья запись в стеке — baz (). Наконец, функция baz выполняет console.log, так что последней записью в стеке является console .log("привет от базы").
Куча. Объекты располагаются в куче, которая является просто именем для обозначения большой, в основном неструктурированной области памяти. JavaScript освобождает разработчиков от ответственности за выделение памяти — JavaScript делает это сам, наряду с объявлением значений.
Цикл обработки событий.Единственная задача цикла обработки событий – просмотреть очередь обратного вызова и, как только в очереди обратного вызова появится что-то ожидающее, отправить этот обратный вызов в стек. Цикл событий отправляет в стек по одной функции обратного вызова за раз, как только стек опустеет. Позже стек выполнит функцию обратного вызова.
Веб-API — они предоставляют данные из браузера и окружающей компьютерной среды и выполняют с ними полезные сложные действия. Они не являются частью самого языка JavaScript, а построены на основе основного языка JavaScript для обработки асинхронных событий, таких какотправка HTTP-запросов, прослушивание событий DOM,задержка выполнения с использованием setTimeout
или setInterval
, кэширование, хранение в базе данных и многое другое. сделать что-то в фоновом режиме и вернуть данные после выполнения, тем временем мы можем продолжить дальнейшее выполнение кода JavaScript.
Теперь давайте обсудим общую картину со всеми обсуждаемыми компонентами.
Когда мы пытаемся запустить этот код,
function printHello() { console.log('Hello from baz'); } function baz() { setTimeout(printHello, 3000); } function bar() { baz(); } function foo() { bar(); } foo();
Здесь foo() сделает первую запись стека в стеке вызовов, затем bar(), затем baz() и, наконец, когда baz() начинает выполняться и выполняет вызов setTimeout
API, JavaScript передаст функцию обратного вызова в Web API и перейти к следующей строке. который будет выталкивать кадры стека в порядке LIFO, поскольку нет следующей строки для выполнения. Сначала выскочит baz(), затем bar() и затем foo().
К этому времени веб-API ожидает завершения в течение 3 секунд. По истечении 3 секунд он поместит этот обратный вызов в очередь обратного вызова, и, поскольку стек пуст, цикл событий поместит этот обратный вызов обратно в стек, где произойдет выполнение этого обратного вызова.
На этом все. Надеюсь, вам понравится.