Вы один из них?

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

Я покажу вам, почему он не существует и почему он даже не может существовать с помощью простого фрагмента кода. (Прежде чем начать, пожалуйста, ознакомьтесь с некоторыми фундаментальными концепциями JS и поймите, что означают все эти пугающие термины, такие как Лексическая среда, синтаксические анализаторы, контексты выполнения.)

Давайте посмотрим на явление, происходящее в JavaScript, которое люди находят удивительным и, возможно, немного сбивающим с толку. У меня здесь моя простая переменная a и function b().

Итак, что бы вы ожидали увидеть? Что ж, я ожидал увидеть “function b called”, а затем “Namaste Human.

Теперь давайте сделаем что-нибудь немного другое, чем в других языках программирования, вы ожидаете, что это вообще не сработает. Я вернусь к коду и перенесу эти вызовы туда, где я вызываю функцию b() и где я выводю значение a в верхнюю часть страницы.

Что ж, в большинстве языков программирования можно ожидать ошибки, потому что языки программирования выполняют свой код по одной строке за раз. Так как мы еще не дошли до функции b(), я пока не могу ее использовать. Это то, чего вы обычно ожидаете. Но в JavaScript это не так.

Он запустил функцию. И вместо того, чтобы выдать ошибку, он дал мне значение, но не Namaste Human, значение, которое я сохранил. Но эта штука называется undefined.🤔

На самом деле эта переменная была мне доступна, хотя ее значение было неправильным. Посмотрите, что произойдет, если я просто удалю переменную a .

Теперь я получаю сообщение об ошибке, что переменная a is not defined.

Но если я верну его где-нибудь в этом файле JavaScript,

Это явление известно как подъем!

Но то, как это объясняется, я думаю, может создать неправильное впечатление. Если вы посмотрите в Интернете, то, как объясняется подъем, это то, что люди говорят, что переменные и функции в JavaScript поднимаются или перемещаются наверх механизмом JavaScript, как если бы они были перемещены физически, вверх, чтобы они не работали. независимо от того, куда вы их положите.

Но теперь мы можем сказать, что это не совсем так, потому что переменная не была установлена ​​в Namaste Human. Итак, это не было похоже на физическое перемещение линии. Он ведет себя примерно так:

Как будто я объявил переменную, а затем установил значение позже. Но все же это не то, что происходит, потому что мы уже сказали: «Выполняется не то, что вы написали». Он переводится движком JavaScript!

Таким образом, это не похоже на то, что движок JavaScript физически переместил код, который вы ввели в код, а затем выполнил его.

Вот код, который мы написали.

Чтобы понять, что делает JavaScript. Нам нужно немного глубже изучить контекст выполнения и то, как он создается. Причина, по которой JavaScript ведет себя так, что переменные и функции в некоторой степени доступны, даже если они написаны позже в коде, заключается в том, что контекст выполнения создается в два этапа.

Первый этап называется этапом создания.

На этом этапе мы знаем, что у нас есть глобальный объект, который настраивается в памяти. Затем у нас есть this, который также устанавливается в памяти.

Помните, что this всегда создается в контексте выполнения. Также создается внешняя среда.

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

И именно этот шаг несколько сбивчиво называют подъемом!

Фактически JavaScript не перемещает код в верхнюю часть страницы. Все это означает, что до того, как ваш код начнет выполняться построчно, движок JavaScript уже выделил пространство памяти для переменных, которые вы создали во всем коде, который вы построили, и всех созданных вами функций, тоже.

Эти функции и переменные уже существуют в памяти. Когда код начинает выполняться построчно, он может получить к ним доступ. Однако, когда дело доходит до переменных, все немного иначе. Функция целиком помещается в область памяти. Тем не менее, следующая фаза, фаза выполнения, где он выполняет ваш кусок вашего кода построчно, то есть когда устанавливаются такие виды присваиваний, где переменная a что-то равняется.

Таким образом, механизм JavaScript, когда он настраивает пространство памяти для переменной a,, не знает, каким в конечном итоге будет ее значение,

Это может быть что угодно,

Объект

Функция

Массив

Строка

Или даже символ,

Пока он не начнет выполнение этого кода, он помещает заполнитель с именем undefined. Этот заполнитель здесь означает, о! Я пока не знаю, что это за значение. Это тот же заполнитель, что и у нас. Если мы его вообще не установим.

«Все переменные в JavaScript изначально имеют значение undefined, а функции целиком находятся в памяти».

Здесь происходит следующее: где-то в лексической среде происходит что-то вроде этого:

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

Хотя технически это работает

Лучше всегда так делать

Тем не менее, теперь мы понимаем, что это такое, когда мы говорим о подъеме. Когда мы говорим об этом сценарии или я могу вызвать функцию, даже если она объявлена ​​позже, это действительно связано с тем фактом, что то, что я написал, не выполняется напрямую. Затем движок JavaScript берет мой код и принимает решения.

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

Странно, правда?

Но не так много, когда вы понимаете, что JavaScript Engine собирается настроить пространство памяти для переменных и функций. Итак, когда код начинает выполняться, переменные и функции уже находятся в памяти компьютера, потому что движок JavaScript изучил ваш код и уже предварительно настроил все, чтобы быть готовым к запуску кода.

Подъем между Var VS Let (и Const)

То, что мы видим ниже для let, справедливо и для const.

Как вы думаете, каким должен быть результат?

Здесь мы снова получаем эталонную ошибку.

Это происходит из-за временной мертвой зоны. Не беспокойтесь об этом пугающем термине. Это просто означает период между созданием переменной и инициализацией, когда вы не можете получить к ней доступ.

Означает ли это, что переменные, объявленные с помощью let и const, НЕ ПОДНИМАЮТСЯ?

ДЕЙСТВУЮТ!

Но как это было в случае var, где объявленным с ним переменным было присвоено значение undefined, в случае let и const: они не инициализируются ключевым словом undefined.

Краткое изложение того, что мы узнали

  • Код, который мы пишем, не выполняется напрямую, но механизм JavaScript затем берет код и принимает решения.
  • Вы можете вызывать функции в JavaScript, даже если он объявлен позже, но это не относится к переменным.
  • Поднимаются переменные и функции в JavaScript. Это не означает, что движок JavaScript перемещает их наверх.
  • Подъем - это соглашение на английском языке, которое мы составили, чтобы обсудить идею лексической области, не думая о лексической области.
  • Переменные, объявленные с помощью var, поднимаются и инициализируются значением undefined.
  • Объявление функции поднимается и инициализируется ссылкой на свою функцию, то есть функции целиком находятся в памяти.
  • Переменные, объявленные с помощью let и const, тоже поднимаются! Но вы не можете получить к нему доступ до своих объявлений. Это связано с временной мертвой зоной.

Проверьте свое понимание:

Теперь вы знаете, что переменные поднимаются, а функция полностью находится в памяти. Поскольку целые функции существуют в памяти во время выполнения, расскажите мне, что происходит с переменными, объявленными внутри функции или IIFE. Их поднимают? Пожалуйста, дайте мне знать ваши ответы в разделе комментариев.

Понравилась запись? Я бы хотел услышать от вас.