Что такое Подъем?
- Подъем делает некоторые типы переменных и функций доступными или пригодными для использования в коде до того, как они будут фактически объявлены.
- Переменные поднимаются на вершину своей области видимости.
- Результат удивителен, потому что интерпретатор JavaScript разделяет объявление и назначение функций и переменных: он «поднимает» ваши объявления на вершину области их действия перед выполнением.
- Перед выполнением, на этапе создания памяти, код сканируется на наличие переменных, и для каждой переменной создается новое свойство в объекте среды переменных и инициализируется с помощью "undefined".
- На этапе выполнения, когда синтаксический анализатор достигает фактической инициализации переменной, переменная в объекте переменной среды (контекст выполнения) инициализируется этим значением.
Приведенный выше пример кода ведет себя следующим образом:
Переменный подъем
Переменные могут быть объявлены с помощью трех ключевых слов в JS: var, let и const.
Подъем переменной зависит от ключевого слова, которое использовалось для ее объявления.
Все переменные в JS поднимаются, но могут или не могут быть доступны до инициализации в зависимости от ключевого слова, используемого для их объявления. Переменные, объявленные с помощью «let» и «const», поднимаются, но, в отличие от «var», к ним нельзя получить доступ до инициализации. Будет выдано исключение, если переменная, объявленная с помощью «let» или «const», будет прочитана до ее инициализации.
Поднятие переменных с помощью VAR
Давайте посмотрим, как ведет себя переменная до и после инициализации.
JS обрабатывает этот фрагмент кода следующим образом:
- Если переменная var объявлена внутри функции, она поднимается наверх функции, но не всего кода.
- Если мы вообще не объявляем переменную, а только инициализируем значение, переменная не поднимается.
Однако приведенный ниже код будет работать. (инициализация перемещена вверх и без объявления)
Поднятие переменных с помощью LET и CONST
Переменные, объявленные с помощью let и const, также поднимаются, но исключение будет выдано, если переменная, объявленная с помощью let или const читается перед инициализацией.
По какой причине перед инициализацией нельзя использовать let и const?
Получают ли они значение по умолчанию undefined, например var?
Ответ на эти вопросы отличается от многих источников, доступных в Интернете:
И let, и const поднимаются и инициализируются с помощью «undefined», но, в отличие от var, они получают отдельное пространство памяти, к которому нельзя получить доступ до фактической инициализации переменных. Это время между подъемом и временем до фактической инициализации переменных называется TDZ (временная мертвая зона). Говорят, что переменная находится во «временной мертвой зоне» (TDZ) с начала блока до завершения объявления.
TDZ и typeof
Это отличается от использования typeof
для необъявленных переменных и переменных, которые содержат значение undefined
:
TDZ в сочетании с лексической областью действия
В цикле:-
Преимущества TDZ:
- Облегчает предотвращение и обнаружение ошибок.
- позволяет избежать некоторых серьезных ошибок, возникающих при использовании переменной перед объявлением, в этом случае либо это должно быть правильное значение переменной, либо ошибка, а не неопределенность.
- Заставляет константные переменные работать.
Функция подъема
Одним из преимуществ подъема является то, что он позволяет вам использовать функцию до того, как вы объявите ее в своем коде. Следует отметить, что поднимаются только объявления функций, а не выражения функций. В этом должен быть смысл: как мы только что узнали, присваивания переменных не поднимаются.
Поднятие объявлений функций
Почему это происходит? Это связано с тем, что на этапе создания памяти объявления функций поднимаются и получают память в содержащей области (здесь — глобальная область) и инициализируются определением функции.
Поднятие функциональных выражений
Выражение функции аналогично объявлению переменной и присвоению ей значения. Единственная разница здесь в том, что значение является анонимной функцией.
Как выглядит функциональное выражение: -
var foo = function () { }. // can use let or const also
Поскольку они являются переменными, присваивания не поднимаются, а только объявление.
Даже если мы можем получить к ним доступ (в случае var), они инициализируются с помощью «undefined», что не является функцией. Это вызовет ошибку.
Выражения функций с LET и CONST
но когда закрывающий блок удаляется: -
Подъем класса
Классы, определенные с помощью объявления класса, поднимаются, что означает, что в JavaScript есть ссылка на класс. Однако класс не инициализируется по умолчанию, поэтому любой код, использующий его до выполнения строки, в которой он инициализирован, вызовет ошибку ссылки.
Источники: -