Курс →React JS

для начинающих
от платформы StackDev.ru

Поднятие в JS (Hoisting в Javascript + 3 примера)

Дата:
Javascript

В этой статье мы с вами разберемся как что такое, и как работает поднятие (Hoisting) в Javascript. Эта одна из базовых тем в ванильном JS и вы однозначно наткнетесь на нее в одном из интервью при устройстве на работу.

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

Поднятие в JS (пример с функцией)

Для нашего примера создадим функцию letsGo и попробуем ее вызвать до ее создания.

1// Вызываем функцию letsGo до ее создания
2letsGo();
3
4function letsGo() {
5 console.log('Go!!');
6}
7
8// В консоли получаем
9// Go!!

Наша функция запускается, и мы получаем строку "Go!!" в нашей консоли. Это происходит, так как срабатывает мехнаизм "поднятие" в Javascript.

То есть, "под капотом" компилятор JS "поднимает" все строчки, где объявляются функции на самый верх.

Ваглядит это так:

1// 1. "Под капотом" - компилятор JS поднимает объявление нашей функции на самый верх:
2// function letsGo() {
3// console.log('Go!!');
4// }
5
6letsGo();
7
8function letsGo() {
9 console.log('Go!!');
10}

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

Теперь, давайте немного расширим наш пример и создадим еще одну функцию add.

1// Запускаем функцию letsGo
2letsGo();
3
4// Объявляем функцию letsGo
5function letsGo() {
6 console.log('Go!!');
7
8 // Запускаем функцию add
9 add(5, 3);
10}
11
12// Объявляем функцию add
13function add(a, b) {
14 return a + b;
15}
16
17// В консоли получаем:
18// Go!!
19// 8

Как мы видим, функция add - принимает 2 значения и возвращает их сумму. Мы также запускаем функцию add до ее создания - внутри нашей первой функции letsGo.

Мы видим, что наша вторая функция add также срабатывает и получаем результат сложения в консоли. То есть, опять, сработал механизм "поднятия" в JS, который поднял весь код, где объявляются функции на самый верх.

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

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

1letsGo();
2// Получаем ошибку
3// Uncaught ReferenceError: can't access lexical declaration 'letsGo' before initialization
4
5// Используем функциональное выражение
6const letsGo = function () {
7 console.log('Go!!');
8};

Если решим написать то же самое, используя стрелочную функцию, тоже получим ошибку ("поднятие" не работает):

1letsGo();
2// Получаем ошибку
3// Uncaught ReferenceError: can't access lexical declaration 'letsGo' before initialization
4
5// Используем стрелочную функцию
6const letsGo = () => {
7 console.log('Go!!');
8};

Поднятие в Javascript (пример с переменной var)

Давайте создадим переменную years, используя var и сразу попробуем вывести ее значение в лог - до ее создания.

1// Выводим значение переменной years - до ее объявления
2console.log(years);
3// Получаем значение undefined
4// undefined
5var years = 100;

Давайте, ради интереса, также выведем в лог произвольную переменную, которой у нас вообще не существует:

1// Выводим значение переменной years - до ее объявления
2console.log(years);
3
4// Выводим в лог вымышленную переменную test
5console.log(test);
6
7// Получаем значение переменной years - undefined
8// undefined
9
10// Для переменной test - получаем ошибку!
11// Uncaught ReferenceError: test is not defined
12
13var years = 100;

То есть, когда мы выводим в лог значение переменной years, до ее создания, происходит следующее:

  1. Компилятор Javascript, под капотом, в самом верху, добавляет строчку с объявлением нашей переменной. То есть, инициализирует переменную со значением undefined.
1// 1. "Под капотом" - JS объявляет нашу переменную на самом верху
2// var years;
3
4// 2. Выводим значение переменной years - до ее объявления
5console.log(years);
6
7// 3. Получаем значение undefined
8// undefined
9var years = 100;
  1. В самомом конце наша переменная обновляется со значением 100
1// 1. "Под капотом" - JS объявляет нашу переменную на самом верху
2// var years;
3
4// 2. Выводим значение переменной years - до ее объявления
5console.log(years);
6
7// 3. Получаем значение undefined
8// undefined
9var years = 100;
10
11console.log(years);
12// 4. Получаем обновленное значение переменной years
13// 100