Коротка відповідь
juniorvar — це функціонально-обмежений, hoisted, не‑block scoped. let і const — блочно обмежені; let reassignable, const не‑reassignable (значення об’єкта можна мутувати). `let a = 1; const b = {x:2}; b.x=3;`
Повне пояснення
Що це і навіщо
var,letтаconst– ключові слова для оголошення змінних у JavaScript. Вони визначають область видимості, можливість переназначення та поведінку під час hoisting.
Ключові принципи/терміни
- Scope:
varмає функціональний (function) scope, аlet/const– блочний (block) scope. - Hoisting: усі оголошення піднімаються вгору, але
varініціалізується значеннямundefined, тоді якlet/constзалишаються у «temporal dead zone» до моменту ініціалізації. - Reassignment:
varіletможна переназначити,const– ні. Однак об’єкти, оголошені черезconst, можна мутувати.
Як це працює (логіка)
- Під час парсингу скрипту інтерпретатор створює «environment record» і піднімає всі
var‑змінні до початку функції, ініціалізуючи їхundefined. Дляlet/constстворюється «temporal dead zone» – період, коли доступ до змінної недоступний. - Після підняття виконується реальна ініціалізація:
varотримує значення, аlet/const– при оголошенні.
Практика і реалізація (JS/TS)
// var – функціональний scope, hoisted
function demoVar() {
console.log(x); // undefined
var x = 10;
}
demoVar();
// let – блочний scope, hoisted без ініціалізації
function demoLet() {
// console.log(y); // ReferenceError: y is not defined
let y = 20;
}
demoLet();
// const – блочний scope, не‑reassignable
const obj = {a:1};
obj.a = 2; // OK – мутуємо
// obj = {}; // TypeError: Assignment to constant variable.
Тестування
- Unit: перевірка поведінки в різних контекстах (функція, блок). Приклад з Jest:
test('var hoisting', () => {
expect(() => { console.log(x); var x = 1; }).not.toThrow();
});
- Integration: перевірка, що
let/constне доступні поза блоком.
Дизайн‑рішення та моделі даних
- У сучасному коді переважно використовують
let/const.varзалишаються лише для підтримки legacy‑коду.
Производительность і масштабування
varстворює змінні в функціональному середовищі, що може збільшувати обсяг пам’яті при великій кількості локальних змінних.let/constкраще працюють з блочним scope, що полегшує оптимізацію JIT‑компілятора.
Безпека і приватність
constзапобігає випадковому переназначенню, що зменшує ризик логічних помилок. Однак мутування об’єктів черезconstвсе одно можливе, тому слід використовуватиObject.freeze()або immutable бібліотеки.
Особливості в контексті JS Core
varпідтримується у всіх браузерах, включно з ES3.let/const– частина ES6+ і потребують транспіляції для старих середовищ.
Оптимізація, типові помилки та edge cases
- Не використовуйте
varу глобальному просторі – це створює глобальні змінні. У блочних конструкціях використовуйтеlet/const. Перевіряйте, що не переназначаєтеconst.
Диагностика і отладка
- Якщо змінна не визначена, перевірте scope:
varможе бути доступним поза блоком, аlet/const– ні.
Альтернативи
- Для констант, що не змінюються, можна використовувати
Object.freeze()або бібліотеки immutable.
Крайні випадки і часті помилки (8)
varв глобальному просторі створює властивість об’єктаwindow. 2. Переназначенняconst→ TypeError. 3. Доступ доlet/constу TDZ → ReferenceError. 4. Внутрішні цикли зvar– одна змінна для всіх ітерацій. 5. Внутрішні цикли зlet– окрема змінна для кожної ітерації. 6. Мутування об’єкта, оголошеного черезconst. 7. Використанняvarу функціях, що викликаються рекурсивно – потенційна колізія. 8. Підняттяlet/constу функціях, що викликаються з різних контекстів.
Cheatsheet + follow‑up питання
var: function scope, hoisted, redeclarable.let: block scope, hoisted (TDZ), reassignable.const: block scope, hoisted (TDZ), non‑reassignable.
Follow‑up: Як let/const впливають на продуктивність JIT‑компілятора?