Области видимости: глобальная, функциональная, блочная
Что такое область видимости? 🧐
Область видимости (scope) — это контекст, в котором переменные видны и могут использоваться. В JavaScript есть три типа областей:
- Глобальная 🌍 — видна везде
- Функциональная 🏠 — ограничена функцией
- Блочная 🧱 — ограничена блоком
{}(появилась в 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();
Алгоритм поиска:
- Ищем переменную в текущей функции
- Если нет — идём во внешнюю функцию
- Если и там нет — проверяем глобальную область
- Если переменной нет — 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 в современном коде!