Мы говорили о фазе создания, когда у нас есть глобальный объект и this, равные друг другу.
Мы также видели этап выполнения, когда мы просто запускаем наш код. Но есть еще одна вещь, которой не хватало на этой картинке: подъем.

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

Переменные частично поднимаются, а функции поднимаются.

Вы можете видеть, что когда мы используем console.log(teddy), мы получаем undefined. Но обратите внимание, что в большинстве языков это не работает так. Но в Javascript мы можем запустить функцию еще до того, как запишем ее.

Когда мы console.log(sing), мы получаем значение. Это происходит из-за подъема.
Это механизм JavaScript, выделяющий память для переменных и функций, которые он видит в вашем коде на этапе создания, прежде чем он его выполнит.

На этапе создания механизм Javascript просматривает код и, как только он видит две вещи: ключевое слово var или ключевое слово function, он выделяет часть памяти, потому что предполагается, что он понадобится на этапе выполнения.

Например, с varteddy = undefined. Он говорит: «Эй, я не знаю, что такое плюшевый, но я знаю, что нам понадобится память для плюшевого — пока назначьте его неопределенным». undefined — это тип Javascript.

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

Вот что значит сказать, что переменные частично подняты. Мы поднимаем переменную, но не правую сторону, не фактическое значение. Мы назначаем его неопределенным.

Теперь функции полностью подняты. Это означает, что объявлению нашей функции (sing) было назначено место в памяти, так что каждый раз, когда мы вызываем sing(), мы знаем, где в памяти находится этот фрагмент текста. Всякий раз, когда мы вызываем sing(), мы можем просто запустить эту функцию.

Но давайте посмотрим, подтвердятся ли наши предположения.

Мы сделали несколько заявлений:
Мы сказали, что как только механизм Javascript увидит ключевое слово function, он поднимет его и освободит место для него. в памяти. Так что, если мы изменим эту функцию так, чтобы слово не было первым?

Мы видим, что получаем ошибку ссылки, потому что sing() не определен. Он не поднимает его, потому что первое, что он увидел, не было var или функцией.

А что, если мы изменим var на const, что соответствует Es6?

const или let не поднимаются, потому что правило является либо переменной, либо функцией. В большинстве языков, где нет подъема, это произойдет.

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

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

И на этапе выполнения, когда мы видим что-то вроде console.log(teddy), движок Javascript скажет, можете ли вы взять teddy из памяти? И когда он смотрит на мишку в памяти, ему присваивается неопределенное значение, потому что ему не было присвоено новое значение.

И это ключевое отличие, особенно когда речь идет о функциях. У нас есть объявления функций, где function — это первое слово в строке или что-то вроде функционального выражения, где мы можем присвоить функцию переменной.

Это функциональное выражение также будет поднято и назначено undefined, в отличие от объявления функции. Функция может работать только на этапе выполнения после ее определения.

Чтобы просмотреть наш глобальный контекст выполнения, у нас есть глобальный объект и этот объект на этапе создания, который назначается. И на этапе выполнения мы запускаем наш код.
Но важно помнить, что на этапе создания у нас также есть этот акт подъема, когда каждый раз, когда мы видим var или ключевое слово function, мы выделяем для них место в нашей куче, чтобы убедиться, что механизм Javascript готов к выполнению.

›››››Вызов функции