Области видимости: глобальная, функциональная, блочная

Что такое область видимости? 🧐

Область видимости (scope) — это контекст, в котором переменные видны и могут использоваться. В JavaScript есть три типа областей:

  1. Глобальная 🌍 — видна везде
  2. Функциональная 🏠 — ограничена функцией
  3. Блочная 🧱 — ограничена блоком {} (появилась в ES6)

Разберём каждый тип на вкусных примерах!


Глобальная область видимости

Переменные, объявленные вне всех функций и блоков, становятся глобальными:

const globalVar = 'Я — глобальная!';

function checkScope() {
  console.log(globalVar); // Доступно!
}

checkScope();
console.log(globalVar); // Тоже доступно

⚠️ Осторожно! Глобальные переменные могут изменяться из любого места кода. Это может привести к неожиданным багам. Используйте их осознанно!


Функциональная область видимости (function scope)

Переменные, объявленные внутри функции, видны только в ней:

function createSecret() {
  const secret = 'Shhh!'; // Локальная переменная

  console.log(secret); // Работает
}

createSecret();
console.log(secret); // Ошибка! secret не определена

🔍 Особенности:

  • Работает для var, const, let
  • Каждая функция создаёт новую область видимости
  • Вложенные функции видят переменные родительских функций (цепочка областей видимости)

Блочная область видимости (block scope)

Появилась в ES6 вместе с let и const. Ограничивает видимость любым блоком {}:

if (true) {
  let blockScoped = 'Видно только в блоке';
  var functionScoped = 'Видно везде в функции';

  console.log(blockScoped); // OK
}

console.log(functionScoped); // OK
console.log(blockScoped); // Ошибка!

🔥 Горячий факт: var игнорирует блоки, поэтому для блочной видимости используйте только let/const!


Лексическое окружение в действии

JavaScript использует цепочку областей видимости для поиска переменных:

const global = '🌍';

function outer() {
  const outerVar = '🏠';

  function inner() {
    const innerVar = '🛋️';
    console.log(global + outerVar + innerVar); // "🌍🏠🛋️"
  }

  inner();
}

outer();

Алгоритм поиска:

  1. Ищем переменную в текущей функции
  2. Если нет — идём во внешнюю функцию
  3. Если и там нет — проверяем глобальную область
  4. Если переменной нет — ReferenceError

Практические примеры

Пример 1: Замыкания

function createCounter() {
  let count = 0;

  return function() {
    return ++count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2

🔮 Магия: Внутренняя функция "запоминает" переменную count из внешней области видимости даже после завершения работы createCounter.

Пример 2: Циклы с let vs var

// С var (проблема)
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100); // 3, 3, 3
}

// С let (решение)
for (let j = 0; j < 3; j++) {
  setTimeout(() => console.log(j), 100); // 0, 1, 2
}

🎯 Суть: let создаёт новую переменную для каждой итерации цикла, а var использует одну и ту же.


Итоговая шпаргалка 📋

Область видимости Где работает? Какие переменные?
Глобальная Везде Все (var, let, const)
Функциональная Внутри функции var, let, const
Блочная Внутри {} Только let, const

💡 Главный совет: Всегда используйте const по умолчанию, а let — только если переменная будет изменяться. Избегайте var в современном коде!

Скрыть рекламу навсегда

🌱 Индвидидулаьные занятия

Индивидуальные онлайн-занятия по программированию для детей и подростков

Личный подход, без воды, с фокусом на понимание и реальные проекты.

🚀 Записаться на занятие