JavaScript: подъем
Прежде чем мы разберемся с подъемом, давайте вкратце познакомимся с контекстом выполнения JavaScript.
Контекст выполнения
Проще говоря, контекст выполнения - это среда, в которой код JavaScript оценивается и выполняется.
Контекст выполнения создается в два этапа:
- Этап создания: На этом этапе создается
this
, глобальный объект (в случае глобального контекста выполнения) и лексическая среда (отображение идентификатора и переменной). На этом этапе он устанавливает объем памяти для переменных и функций. - Этап выполнения. На этом этапе происходит присвоение переменных и выполнение кода.
Теперь давайте взглянем на фрагмент кода:
var a = 20; console.log(a); Output: 20
Давайте изменим приведенные выше строки кода на это:
console.log(a); console.log(b); var a = 20; Output: undefined ReferenceError: b is not defined
Итак, почему console.log(a)
в приведенном выше фрагменте кода - это undefined
и почему не выдает ошибку, что a
не определен, хотя мы пытаемся получить к нему доступ еще до того, как он объявлен?
Это из-за подъема.
Подъем: процесс настройки пространства памяти для переменных и функций на этапе создания контекста выполнения.
Даже до начала выполнения кода движок JavaScript устанавливает пространство оперативной памяти для всех переменных и функций, используемых в коде на этапе создания (т. Е. Объявления переменных и объявления функций хранятся в памяти), тогда как присвоение переменной происходит на этапе выполнения (когда код выполняется).
Итак, для приведенного выше фрагмента кода, когда код выполняется (фаза выполнения), переменная a
уже находится в памяти, и по умолчанию переменные var
имеют значение undefined. Поскольку наш console.log(a)
находится перед присвоением a, он отображает undefined
.
Вот что происходит с переменными var. Теперь посмотрим, как работают let и const.
let и const:
console.log(a); let a = 20; output: ReferenceError: Cannot access 'a' before initialization
Это не означает, что let и const не поднимаются. Но в отличие от var, который инициализируется значением undefined
, let и const не инициализируются ничем (на этапе создания) до тех пор, пока мы не встретим объявление переменной на этапе выполнения. Этот промежуток от создания переменной в памяти до момента, когда мы обнаруживаем объявление переменной на этапе выполнения, называется Временная мертвая зона, и в течение этого периода доступ к переменным невозможен.
let a; const b = 10; console.log(a); console.log(b); a = 50; output: undefined 10
Примечание. Мы не можем просто объявить переменную const и не присвоить ей значение. т.е. const b;
не допускается. Кинул бы SyntaxError: Missing initializer in const declaration
.
Теперь, когда мы знаем, как подъем работает для переменных (var, let и const), давайте взглянем на подъем функции.
Функция:
Это работает аналогично подъему переменных. Однако давайте рассмотрим два способа определения функций в javascript и то, как подъем работает в обоих случаях:
- Объявления функций
- Функциональные выражения
1. Объявления функций
display(); function display() { console.log("Hello World!"); } output: Hello World!
Мы знаем, что переменные и функции помещаются в память (на этапе создания контекста выполнения) еще до начала выполнения кода. Здесь полная функция помещается в память на этапе создания. Итак, когда выполнение начинается, и мы сталкиваемся с вызовом функции, функция выполняется.
2. Функциональные выражения
display(); var display = function() { console.log("Hello World!"); } output: TypeError: display is not a function
Итак, вы уже знаете упражнение. JavaScript обнаруживает display
переменную на этапе создания, он сохраняет переменную в памяти, и, поскольку это var
, отображение инициализируется на undefined
. Позже, на этапе выполнения, когда мы сталкиваемся с вызовом функции display()
, в этот момент display
- это просто переменная в памяти. Итак, получаем display is not a function
ошибку.
Если мы разместим вызов функции после присвоения функции переменной, на выходе будет Hello World!
.
Удачного кодирования 🙂