Область видимости в JavaScript: разбираем var, let и const на примерах (JavaScript)

Область видимости говорит, где в коде переменная «живёт» и где её можно использовать. Если не учитывать правила для var/let/const, код будет выдавать странные значения или падать с ошибками. Дальше — только факты и примеры, которые можно сразу проверить.


var: живёт по функции, всплывает, разрешает повтор

Что это значит на практике:

  • Виден во всей функции, блок {} его не ограничивает.
  • Объявление всплывает наверх функции, но до присваивания значение будет undefined.
  • Можно два раза написать var x в одной области — ошибки не будет.

Пример 1: var внутри if — виден снаружи

js
function demoVar() {
  if (true) {
    var x = 10;
  }
  console.log(x); // 10
}
demoVar();

Здесь x доступен после if, потому что для var блок не создаёт отдельную область.

Пример 2: цикл с var — счётчик остаётся после цикла

js
for (var i = 0; i < 3; i++) {}
console.log(i); // 3

Переменная i продолжает существовать после цикла. Это легко ломает логику, если дальше в коде есть своя i.

Пример 3: обращение до объявления → undefined

js
console.log(z); // undefined
var z = 5;

Фактически JS обрабатывает это так:

js
var z;
console.log(z); // undefined
z = 5;

Из‑за этого бывает трудно понять, почему значение не то.

Пример 4: повторное объявление var без ошибки

js
var a = 1;
var a = 2;
console.log(a); // 2

В большом файле легко случайно продублировать имя и незаметно поменять значение.


let: живёт только в блоке, нельзя повторно объявить, до объявления — ошибка

Что это значит на практике:

  • Область — блок {}: if, for, while, любые фигурные скобки.
  • Нельзя два раза объявить let x в одном блоке — будет ошибка.
  • До строки объявления переменная недоступна: попытка прочитать вызовет ReferenceError, а не undefined.

Пример 1: let внутри if — снаружи его нет

js
function demoLet() {
  if (true) {
    let y = 20;
  }
  // console.log(y); // ReferenceError: y is not defined
}
demoLet();

Блок реально изолирует переменную.

Пример 2: цикл с let — счётчик не виден после цикла

js
for (let j = 0; j < 3; j++) {}
// console.log(j); // ReferenceError: j is not defined

Цикл не «оставляет мусор» снаружи.

Пример 3: нельзя дважды объявить let в одном блоке

js
let b = 1;
// let b = 2; // SyntaxError: Identifier 'b' has already been declared

Это защищает от случайных перезаписей.

Пример 4: до объявления трогать нельзя

js
// console.log(c); // ReferenceError: Cannot access 'c' before initialization
let c = 3;

Если порядок перепутан — сразу ошибка, её проще заметить.


const: как let, но нельзя переназначить

Что это значит на практике:

  • По области видимости ведёт себя как let (блок {}).
  • Нельзя сделать const x = ... и потом x = ....
  • Для объектов и массивов можно менять свойства/элементы, но нельзя присвоить новую ссылку.

Пример 1: нельзя переназначить const

js
const d = 4;
// d = 5; // TypeError: Assignment to constant variable

Пример 2: const в блоке — снаружи не виден

js
if (true) {
  const e = 5;
}
// console.log(e); // ReferenceError: e is not defined

Пример 3: содержимое менять можно, ссылку — нет

js
const arr = [1, 2];
arr.push(3);      // ок: [1, 2, 3]
// arr = [4, 5];   // ошибка
 
const obj = { name: 'test' };
obj.name = 'new';  // ок
// obj = {};        // ошибка

Где чаще всего случаются проблемы

  • var в цикле: счётчик остаётся снаружи и случайно влияет на дальнейший код.
  • Обращение к переменной до объявления: с var получаешь undefined и долго ищешь ошибку; с let/const сразу падает с понятной ошибкой.
  • Повторное объявление: var тихо перезапишет значение, let/const не даст этого сделать.
  • Ожидание, что const делает объект «неизменяемым»: на деле он защищает только ссылку, а не содержимое.

Добавить комментарий