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 секунд он поместит этот обратный вызов в очередь обратного вызова, и, поскольку стек пуст, цикл событий поместит этот обратный вызов обратно в стек, где произойдет выполнение этого обратного вызова.

На этом все. Надеюсь, вам понравится.