Підняття
Підняттям (підніманням) JavaScript називають процес, при якому здається, ніби інтерпретатор переміщує оголошення функцій, змінних, класів та імпортів нагору їхньої області видимості, перед виконанням коду.
Підняття не є терміном, нормативно визначеним у специфікації ECMAScript. Специфікація визначає групу оголошень як HoistableDeclaration (піднімне оголошення), але це стосується лише оголошень function
, function*
, async function
і async function*
. Підняття нерідко вважається також можливістю оголошень var
, хоч і в інший спосіб. Простими словами, будь-яку з наступних логік можна вважати підняттям:
- Змога використовувати значення змінної в її області видимості до рядка, в якому вона оголошена. ("Підняття значення")
- Змога звертатися до змінної в її області видимості до рядка, в якому вона оголошена, без викидання
ReferenceError
, проте її значенням завжди єundefined
. ("Підняття оголошення") - Оголошення змінної призводить до зміни поведінки її області видимості до рядка, в якому вона оголошена.
- Побічні ефекти оголошення виробляються до виконання решти коду, що вміщає це оголошення.
Чотири оголошення функцій, перелічені вище, піднімаються з логікою типу 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
не обмежується блоками.
Більше про підняття читайте:
- Підняття
var
,let
іconst
: Посібник з граматики та типів - Підняття
function
: Посібник з функцій - Підняття
class
: Посібник з класів - Підняття
import
: Модулі JavaScript