Підйом у JavaScript: Проста концепція, яка може вас обдурити

pic

Хоістинг в JavaScript

Хоістинг — одне з найбільш поширених питань на співбесідах з JavaScript, яке часто вважається концепцією для початківців. Однак його поведінка може бути оманливою, і навіть досвідчені розробники можуть потрапити в пастки.

Що таке Хоістинг?

Хоістинг в JavaScript — це поведінка, коли оголошення змінних та функцій переміщуються на початок їхнього контексту (скрипт чи функція) під час фази компіляції, до виконання коду.

Переміщуються лише оголошення, а не ініціалізації чи присвоєння.

Хоістинг має різну поведінку для змінних, функцій і класів. Давайте розберемо їх по черзі.

Хоістинг змінних

Хоістинг для змінної, оголошеної через var

  • Змінні, оголошені за допомогою var, підлягають хоістингу, але їх ініціалізація залишається на місці.
console.log(a); // Вивід: undefined (оголошення піднято, не ініціалізація)  
var a = 5;  
console.log(a); // Вивід: 5

2.
Хоістинг для змінних, оголошених через let і const

  • Змінні, оголошені через let і const, також підлягають хоістингу, але вони не доступні до моменту свого оголошення через так звану "тимчасову мертву зону" (temporal dead zone).
console.log(b); // ReferenceError: Cannot access 'b' before initialization   
console.log(c); // ReferenceError: Cannot access 'c' before initialization   
let b = 10;   
const c = 'alphabet';

Хоістинг функцій

  • Оголошення функцій повністю підлягають хоістингу, що означає, що функцію можна викликати до її визначення.
greet(); // Вивід: Hello!   
function greet() {   
 console.log("Hello!");   
}
  • Функціональні вирази (за допомогою var, let або const) не підлягають повному хоістингу; піднята лише змінна, але не присвоєння функції.
sayHello(); // TypeError: sayHello is not a function   
var sayHello = function() {   
 console.log("Hello!");   
};

Хоістинг класів

  • Класи не підлягають хоістингу так, як функції.
    Використання класу до його оголошення призведе до помилки ReferenceError.
const obj = new MyClass(); // ReferenceError: Cannot access 'MyClass' before initialization   
class MyClass {   
 constructor() {   
 console.log("Hello from MyClass!");   
 }   
}

Корисно пам'ятати

  • Хоістинг відбувається в межах тієї області видимості (scope), де змінна або функція були оголошені. Змінні, оголошені всередині функції, піднімаються до верху області видимості цієї функції.
  • Для let і const існує "тимчасова мертва зона" (temporal dead zone) з початку блоку до моменту, поки не буде зустрінуте оголошення змінної.
    У цей період доступ до змінної призведе до помилки ReferenceError.

Кілька найкращих практик

  • Оголошуйте змінні та функції на початку їхньої області видимості, щоб уникнути плутанини та помилок.
  • Уникайте використання var у сучасному JavaScript, надавайте перевагу let та const.
  • Розумійте різницю між оголошеннями функцій та виразами функцій, щоб уникнути помилок.

Додаткова інформація

Тимчасова мертва зона (TDZ) — це проміжок часу між початком області видимості змінної та її оголошенням у коді. Під час цього періоду доступ до змінної призведе до помилки ReferenceError.

Чому існує TDZ?

  1. Передбачувана поведінка
    TDZ гарантує, що змінні не будуть використані до того, як вони будуть правильно оголошені та ініціалізовані.
  2. Запобігання поширеним помилкам
    Без TDZ змінні можуть мати невизначені або непередбачувані значення до ініціалізації, що призводить до проблем, які важко відлагодити.
    3.
    Сприяє декларативному коду
    Вимога оголошувати змінні до їх використання допомагає писати більш зрозумілий і структурований код.

Хоча хоістинг може здаватися простим поняттям, його нюанси можуть збити з пантелику навіть досвідчених розробників. Розуміючи, як обробляються оголошення за лаштунками, ви зможете писати чистіший і більш передбачуваний код та успішно пройти складні інтерв'ю. Пам'ятайте, що опанування основ — це перший крок на шляху до того, щоб стати професіоналом JavaScript! Успіхів у програмуванні!

Перекладено з: Hoisting in JavaScript: The Simple Concept That Can Trick You

Leave a Reply

Your email address will not be published. Required fields are marked *