В этом руководстве вы узнаете о поднятии переменных и объявлений функций в JavaScript и о том, как это работает внутри.
Когда механизм JavaScript выполняет код JavaScript, он создает глобальный контекст выполнения. Глобальный контекст выполнения состоит из двух фаз: создание и выполнение.
На этапе создания механизм JavaScript перемещает объявления переменных и функций в начало кода. Эта функция известна как поднятие или подъем в JavaScript.
Подъем переменных
Подъем переменных означает, что движок JavaScript перемещает объявления переменных в начало скрипта. Например, в следующем примере объявляется переменная counter и инициализируется ее значение равным 1 :
console.log(counter); // undefined var counter = 1;
В этом примере мы ссылаемся на переменную счетчика перед объявлением.
Однако первая строка кода не вызывает ошибки. Причина в том, что движок JavaScript перемещает объявление переменной в начало скрипта.
Технически код на этапе выполнения выглядит следующим образом:
var counter; console.log(counter); // undefined counter = 1;
На этапе создания глобального контекста выполнения механизм JavaScript помещает переменную counter в память и инициализирует ее значение равным undefined.
Ключевое слово let
Следующее объявляет переменную counter с помощью ключевого слова let :
console.log(counter); let counter = 1;
JavaScript выдает следующую ошибку:
"ReferenceError: Cannot access 'counter' before initialization
Сообщение об ошибке объясняет, что переменная счетчика уже находится в куче памяти. Однако он не был инициализирован.
За кулисами движок JavaScript поднимает объявления переменных, в которых используется ключевое слово let. Однако он не инициализирует let.
Обратите внимание, что если вы обращаетесь к несуществующей переменной, JavaScript выдаст другую ошибку:
console.log(alien); let counter = 1;
Вот ошибка:
"ReferenceError: alien is not defined
Подъем функций
Как и переменные, движок JavaScript также поднимает объявления функций. Это означает, что движок JavaScript также перемещает объявления функций в начало скрипта.
Например:
let x = 20,
y = 10;
let result = add(x, y);
console.log(result);
function add(a, b) {
return a + b;
}В этом примере мы вызвали функцию add() перед ее определением. Приведенный выше код эквивалентен следующему:
function add(a, b){
return a + b;
}
let x = 20,
y = 10;
let result = add(x,y);
console.log(result);На этапе создания контекста выполнения механизм JavaScript помещает объявление функции add() в динамическую память. Чтобы быть точным, механизм JavaScript создает объект типа Function и ссылку на функцию с именем add, которая ссылается на объект функции.
Функциональные выражения
В следующем примере add из обычной функции заменяется выражением функции:
let x = 20,
y = 10;
let result = add(x,y);
console.log(result);
var add = function(x, y) {
return x + y;
}Если вы выполните код, произойдет следующая ошибка:
"TypeError: add is not a function
На этапе создания глобального контекста выполнения механизм JavaScript создает переменную add в памяти и инициализирует ее значение равным undefined.
При выполнении следующего кода add не undefined, следовательно, это не функция:
let result = add(x,y);
Переменная add назначается анонимной функции только на этапе выполнения глобального контекста выполнения.
Стрелочные функции
В следующем примере выражение add функции заменяется функцией стрелки:
let x = 20, y = 10; let result = add(x,y); console.log(result); var add = (x, y) => x + y;
Код также выдает ту же ошибку, что и пример функционального выражения, потому что стрелочные функции являются синтаксическим сахаром для определения функциональных выражений.
"TypeError: add is not a function
Подобно выражениям функций, функции со стрелками не поднимаются.
Заключение
- Поднятие в JavaScript происходит на этапе создания контекста выполнения, который перемещает объявления переменных и функций в начало сценария.
- Движок JavaScript поднимает переменные, объявленные с помощью ключевого слова
let, но не инициализирует их как переменные, объявленные с помощью ключевого словаvar. - Движок JavaScript не поднимает функциональные выражения и стрелочные функции.
