Что такое hoisting(всплытие) в JavaScript? Flashcards

1
Q

Что такое hoisting(всплытие) в JavaScript?

A

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

Подниманием называется поведение, при котором JavaScript перемещает объявления переменных, функций и классов в начало области видимости на этапе компиляции. Иногда это может привести к неожиданным результатам, особенно при использовании выражений var, let, const или функций.

Подъем применяется к объявлениям переменных и функций.
Инициализации не запускаются, это всего лишь объявления.
Переменные «var» поднимаются с неопределённым значением, в то время как «let» и «const» поднимаются, но остаются в «мёртвой зоне» до инициализации.

Временная мёртвая зона (TDZ)является важным понятием в подъёме переменных в JavaScript. Она относится к периоду между входом в область видимости (например, функцию или блок) и фактической инициализацией переменной, объявленной с помощью let или const. В течение этого времени любая ссылка на переменную до её инициализации приведёт к ошибке ReferenceError.

Как работает TDZ?
- Переменные, объявленные с помощью let и const, поднимаются в начало области видимости, но не инициализируются до тех пор, пока не будет достигнута строка их объявления.
- Любая попытка получить доступ к этим переменным до их объявления приведет к ошибке.
- TDZ существует только для переменных, объявленных с помощью let и const. Переменные, объявленные с помощью var, не имеют этой проблемы, так как они поднимаются и инициализируются значением undefined.
hello(); // TypeError: hello is not a function
var hello = function() {
console.log(“Hi!”);
};
Переменная hello поднимается в верхнюю часть области видимости, но не инициализируется до тех пор, пока не будет достигнута строка присваивания, поскольку она содержит функциональное выражение. Таким образом, вызов hello() до её инициализации приводит к ошибке TypeError.

  1. Переменный подъем с помощью var
    Когда вы используете var для объявления переменной, объявление поднимается наверх, но его значение не присваивается до тех пор, пока выполнение кода не достигнет инициализации переменной. Это приводит к тому, что на этапе поднятия переменной присваивается неопределённое значение.
    console.log(a); // undefined
    var a = 5;
    Объявление var a перемещается в начало, но a инициализируется значением undefined. Следовательно, при выводе в журнал будет отображаться значение undefined.
  2. Переменный подъем с помощью let и const
    В отличие от var, let и const также поднимаются, но они остаются в временной мёртвой зоне (TDZ) с начала блока до тех пор, пока не встретится их объявление. При обращении к ним до их объявления будет выдана ошибка ReferenceError.
    console.log(b); // ReferenceError: Cannot access ‘b’ before initialization
    let b = 10;
    Переменная поднимается, но находится в временной мёртвой зоне (TDZ) до тех пор, пока не будет выполнена строка объявления.
  3. Объявление функции Подъема
    Объявления функций поднимаются вместе с их именами и телом функции. Это означает, что функцию можно вызвать до её определения в коде.
    greet(); // “Hello, world!”
    function greet() {
    console.log(“Hello, world!”);
    }
    Объявление функции поднимается вверх, и всё определение функции становится доступным до того, как оно будет использовано в коде.
  4. Подъем выражения функции
    Функциональные выражения обрабатываются как объявления переменных. Сама переменная поднимается, но функциональное выражение не присваивается до выполнения строки. Это означает, что вызов функции до её присвоения приведёт к ошибке.
    hello(); // TypeError: hello is not a function
    var hello = function() {
    console.log(“Hi!”);
    };
    Переменная hello поднимается, но, поскольку это функциональное выражение, она не инициализируется до выполнения строки.
  5. Подъем с функциями let и const в
    Переменные, объявленные с помощью let и const внутри функции, поднимаются в начало области видимости функции, но остаются в TDZ. Это предотвращает доступ к ним до их инициализации.
    function test() {
    console.log(x); // ReferenceError: Cannot access ‘x’ before initialization
    let x = 50;
    }
    test();
    Переменная x перемещается внутрь функции, но не может быть доступна до строки её объявления из-за TDZ.
  6. Подъем с помощью классов
    Классы поднимаются наверх, но к ним нельзя получить доступ до их объявления, что приводит к ошибке ReferenceError.
    const obj = new MyClass(); // ReferenceError
    class MyClass {
    constructor() {
    this.name = “Example”;
    }
    }
    Хотя класс MyClass поднимается, к нему нельзя получить доступ до его объявления из-за TDZ, поэтому в коде возникает ошибка ReferenceError.
  7. Повторное объявление переменных с помощью var
    С помощью var можно повторно объявить переменную в той же области видимости. Это уникальное поведение по сравнению с let и const.
    var a = 10;
    var a = 20; // No error
    console.log(a); // 20
    При использовании var второе объявление перезаписывает первое без выдачи ошибки.
  8. Доступ к переменным, объявленным позже в циклах
    При использовании var в циклах переменная цикла переносится в функцию или глобальную область видимости, что может привести к неожиданному поведению. Если вы используете let, переменная имеет область видимости блока и ведёт себя ожидаемым образом.
    for (var i = 0; i < 3; i++) {
    setTimeout(function() {
    console.log(i); // 3, 3, 3
    }, 100);
    }
    Переменная i поднимается, и все функции setTimeout используют одну и ту же ссылку на i, что приводит к значению 3 после завершения цикла.
  9. Использование поднятых функций с параметрами
    Функции могут быть подняты вместе со своими параметрами, но любые параметры, передаваемые в функцию, по-прежнему определяются вызовом, а не поднятием.
    test(10); // 10
    function test(num) {
    console.log(num);
    }
    Вся функция, включая её параметры, поднимается и становится доступной для использования до того, как функция будет объявлена в коде.
  10. Подъем во вложенных функциях
    Поднятие переменных работает и во вложенных функциях. Переменные, объявленные с помощью var внутри функции, поднимаются в начало области видимости этой функции.
    function outer() {
    console.log(a); // undefined
    var a = 5;
    function inner() {
    console.log(b); // undefined
    var b = 10;
    }
    inner();
    }
    outer();
    И a, и b поднимаются в пределах своих областей видимости (внешней и внутренней функций), но их значения не устанавливаются до тех пор, пока выполнение кода не достигнет строк инициализации.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly