Підняття

{{GlossarySidebar}}

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

Підняття не є терміном, нормативно визначеним у специфікації ECMAScript. Специфікація визначає групу оголошень як HoistableDeclaration (піднімне оголошення), але це стосується лише оголошень function, function*, async function і async function*. Підняття нерідко вважається також можливістю оголошень var, хоч і в інший спосіб. Простими словами, будь-яку з наступних логік можна вважати підняттям:

  1. Змога використовувати значення змінної в її області видимості до рядка, в якому вона оголошена. ("Підняття значення")
  2. Змога звертатися до змінної в її області видимості до рядка, в якому вона оголошена, без викидання ReferenceError, проте її значенням завжди є undefined. ("Підняття оголошення")
  3. Оголошення змінної призводить до зміни поведінки її області видимості до рядка, в якому вона оголошена.
  4. Побічні ефекти оголошення виробляються до виконання решти коду, що вміщає це оголошення.

Чотири оголошення функцій, перелічені вище, піднімаються з логікою типу 1; оголошення var піднімається з логікою типу 2; оголошення let, const і class (вони також разом звуться лексичними оголошеннями) піднімаються з логікою типу 3; оголошення import піднімаються з логікою типу 1 і типу 4.

Дехто віддає перевагу вважати, що let, const і class не піднімаються, оскільки темпоральна мертва зона суворо забороняє будь-яке використання таких змінних до їхнього оголошення. Така розбіжність думок є припустимою, оскільки підняття – це не загально узгоджений термін. Однак темпоральна мертва зона може призводити до інших помітних змін у її області видимості, що свідчить про якогось роду підняття:

const x = 1;
{
  console.log(x); // ReferenceError
  const x = 2;
}

Якби оголошення const x = 2 взагалі не піднімалося (тобто вступало в дію лише тоді, коли виконується), то інструкція console.log(x) повинна була б мати змогу зчитати значення x з зовнішньої області видимості. Проте у зв'язку з тим, що оголошення const все ж "забруднює" всю область видимості, в якій визначено, інструкція console.log(x) зчитує значення x з оголошення const x = 2, яке ще не ініціалізовано, і викидає ReferenceError. А проте, більш корисним може бути опис лексичних оголошень як непіднімальних, тому що з боку корисності підняття цих оголошень не приносить жодних змістовних можливостей.

Зверніть увагу, що наступне не є формою підняття:

{
  var x = 1;
}
console.log(x); // 1

Тут немає "доступу до оголошення"; це можливо просто тому, що оголошення var не обмежується блоками.

Більше про підняття читайте:

Дивіться також