Добро пожаловать в увлекательный мир JavaScript — языка программирования, который существует с 1995 года и носит разные названия, такие как JS или ECMAScript. Возможно, вы сталкивались с этим в своем путешествии по веб-разработке или слышали, как другие говорят об этом. Но задумывались ли вы когда-нибудь, что происходит за кулисами, когда ваш код выполняется?

Давайте изучим тонкости его однопоточной, интерпретируемой природы и узнаем, как каждая строка кода обрабатывается движком JavaScript браузера. Итак, приготовьтесь к путешествию, которое проведет нас через поток выполнения, глобальную память, контекст выполнения, локальную память и, наконец, к нашему последнему пункту назначения: стеку вызовов. ⛵️

Эти концепции необходимы для понимания того, что на самом деле происходит, когда вы пишете и выполняете код JavaScript. Итак, пристегнитесь и вперед!

Поток и контекст выполнения

Как упоминалось ранее, JavaScript — это однопоточный и синхронный язык, что означает, что он может выполнять только одну задачу за раз, следуя определенному порядку выполнения, начиная с сверху вниз.

Когда механизм JavaScript встречает файл сценария, он создает Контекст выполнения, отвечающий за преобразование и выполнение каждой строки кода. Этот процесс можно разделить на две фазы: Создание и Выполнение.

На этапе Создание механизм JavaScript выполнит весь исходный код, создаст глобальный контекст выполнения, создаст экземпляр глобального объекта (window в браузере и global в NodeJs), настройте глобальную память и сохраните функции ссылки и значения как неопределенные, когдаони объявляютсяс помощью ключевого словаvar.

Как только начинается фаза Выполнение, JavaScript проходит по коду, обрабатывая каждую строку по мере ее появления. По мере продвижения он присваивает значения каждому атрибуту в памяти.📝

Глобальная и локальная память

Глобальная память — это память, выделенная на этапе Создания контекста выполнения, упомянутом выше.👆 Поскольку она является глобальной, вы можете получить доступ ко всему, что в ней хранится, в любое время!

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

Используя тот же фрагмент кода в качестве примера:

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

Стек вызовов

С помощью стека вызовов Javascript отслеживает все контексты и порядок выполнения.

Для этой цели он использует принцип «последний пришел, первый ушел» — LIFO для более близких друзей 😉 — всегда возвращаясь в конец стека, который является глобальным контекстом.

После выделения памяти для константы num и для функций add2 и square код переходит к выделению памяти для output, которая пуста, а затем вызывает square(), а затем add2() в стек вызовов.

После выполнения каждой функции она будет удалена из стека вызовов.

Напоминает детскую игрушку Качай стопку, но нижняя часть, как global(), никогда не покидает стопку.

Стек вызовов имеет фиксированный размер в зависимости от системы или браузера. Если количество контекстов превышает лимит, возникает ошибка переполнения стека. Это часто происходит с рекурсивной функцией, в которой отсутствует базовое условие, в результате чего программа застревает в бесконечном создании контекстов, добавляемых поверх стека. 🥹👆

Завершаем 🥳

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

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

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

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

Удачного кодирования! 🚀

Талита