Добро пожаловать в увлекательный мир 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, продолжайте изучать эти концепции и не стесняйтесь экспериментировать и применять свои знания.
Если вы хотите узнать больше об этих концепциях, я бы порекомендовал вам следующие ресурсы:
- ⚡️⛓JavaScript Visualized: Scope (Chain)
- 🔥🕺🏼 Визуализация JavaScript: подъем
- JavaScript: сложные моменты, v2
Удачного кодирования! 🚀
Талита