Поднятие (hoisting) в JS

В этой статье вы познакомитесь с понятием hoisting в JavaScript.

Поднятие (hoisting) — это поведение, при котором функцию или переменную можно использовать до объявления.

Поднятие предполагает, что объявления переменных и функций физически перемещаются в начало кода — «поднимается».

Например:

// используем переменную test
console.log(test);   // вывод: undefined
// объявляем переменную test
var test;

Эта программа выведет в консоль значение undefined.

Аналогично ведет себя такая программа:

// объявляем переменную
var test;
// используем переменную
console.log(test); // вывод: undefined

Поскольку переменная test объявлена, но не инициализирована (ей ни присвоено никакое значение), JavaScript определяет ее как undefined.

Поднятие переменных

Ключевое слово var поддерживает hoisting, а вот let и const — нет.  

Пример:

a = 5;
console.log(a);
var a; // значение a — 5

В приведенном выше примере переменная a используется до объявления. Программа работает и выводит на экран значение 5.

Аналогично будет работать следующая программа:

var a;
a = 5;
console.log(a); // значение a — 5

Не поддерживает инициализацию

JavaScript не поддерживает поднятие с инициализацией. То есть так hoisting работать не будет: 

console.log(a); // вывод: undefined
var a = 5;

Аналогично будет работать следующая программа:

var a;
console.log(a); // вывод: undefined
a = 5;

На этапе компиляции в память переносится только объявление. Поэтому значение переменной aundefined, поскольку мы выводи на экран a без инициализации.

Внутри функции — поднятие только до начала функции

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

// program to display value
var a = 4;

function greet() {
    b = 'привет';
    console.log(b); 
    var b;
}

greet(); // вывод: привет
console.log(b);

Вывод:

привет
Uncaught ReferenceError: b is not defined

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

Примечание. При объявлении переменной с поднятием переменная доступна только в той области видимости, в которой она объявлена.

С let нельзя

Если переменная объявлена с помощью ключевого слова let, применить к ней hoisting нельзя. 

a = 5;
console.log(a);
let a; // ошибка

Вывод:

Uncaught ReferenceError: Cannot access 'a' before initialization

При использовании let сначала объявление, потом использование.

Поднятие функций

Функцию можно также вызвать до ее объявления. 

greet();

function greet() {
    console.log('Приветики.');
}

Вывод:

Приветики.

В это примере функция greet() вызывается до ее объявления, и программа все равно показывает вывод. Это происходит из-за hoisting.

С функциональными выражениями нельзя

Если определить функцию в виде выражения при поднятии, возникнет ошибка. Причина: поднимаются только объявления.  

greet();

let greet = function() {
    console.log('Приветики.');
}

Вывод:

Uncaught ReferenceError: greet is not defined

Использование var здесь не поможет. Все равно будет ошибка: 

Uncaught TypeError: greet is not a function

Примечание. Поднятие не используется в других языках программирования: Python, C, C++, Java.

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

А в случае с переменными лучше использовать let, а не var.

codechick

СodeСhick.io - простой и эффективный способ изучения программирования.

2024 ©