Поднятие

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

Узнаем больше

Пример

Одним из преимуществ помещения в память объявлений функций до выполнения кода является возможность использовать функцию до её объявления. Например:

js
function catName(name) {
  console.log("Мою кошку зовут " + name);
}

catName("Тигр");
/*
Результатом будет вывод строки: "Мою кошку зовут Тигр"
*/

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

js
catName("Раиса");

function catName(name) {
  console.log("Мою кошку зовут " + name);
}
/*
Результатом будет вывод строки: "Мою кошку зовут Раиса"
*/

Даже если мы вызываем функцию до её объявления, код работает. Это происходит благодаря тому, как работает контекст выполнения в JavaScript.

Hoisting хорошо работает и с другими типами данных и переменными. Переменные могут быть инициализированы и использованы до их объявления. Однако, они не могут быть использованы без инициализации.

Пример:

num = 6;
num + 7;
var num;
/* не генерирует ошибку, так как num объявлен */

JavaScript "поднимает" только объявление, но не инициализацию. Если вы исполь��уете переменную, объявленную и проинициализированную после её использования, то значение будет undefined. Два примера ниже демонстрируют это поведение.

var x = 1; // Инициализируем x
console.log(x + " " + y);  // '1 undefined'
var y = 2;
//код выше и код ниже одинаковые

var x = 1; // Инициализируем x
var y; // Объявляем y
console.log(x + " " + y);  // '1 undefined'
y = 2; // Инициализируем y

Technical reference