Что такое область видимости (Scope) в JavaScript?
1. Определение
Область видимости (Scope) — это контекст, в котором доступны переменные, функции и объекты.
Область видимости определяет, откуда можно получить доступ к переменной или функции, а также где они существуют в коде.
2. Типы областей видимости в JavaScript
2.1. Глобальная область видимости (Global Scope)
Переменные, объявленные вне функций или блоков кода, имеют глобальную область видимости.
Они доступны в любом месте кода.
let globalVar = "Я глобальная переменная";
function showGlobal() {
console.log(globalVar); // Доступна внутри функции
}
showGlobal();
console.log(globalVar); // Доступна везде
Внимание:
Глобальные переменные засоряют пространство имён и могут привести к конфликтам.
2.2. Функциональная область видимости (Function Scope)
Переменные, объявленные с var
, let
, const
внутри функции, доступны только внутри этой функции.
function myFunction() {
let functionVar = "Я внутри функции";
console.log(functionVar); // Работает
}
myFunction();
console.log(functionVar); // Ошибка: переменная не определена
Здесь functionVar
недоступна за пределами myFunction
.
2.3. Область видимости блока (Block Scope)
Переменные, объявленные с let
и const
, имеют блочную область видимости, то есть существуют только внутри {}
.
{
let blockVar = "Я внутри блока";
console.log(blockVar); // Работает
}
console.log(blockVar); // Ошибка: переменная не определена
Важно: var
не поддерживает блочную область видимости.
{
var test = "Я объявлена с var";
}
console.log(test); // "Я объявлена с var" — переменная утекла в глобальную область
2.4. Лексическая область видимости (Lexical Scope)
Вложенные функции могут использовать переменные из внешних областей, но не наоборот.
function outerFunction() {
let outerVar = "Я во внешней функции";
function innerFunction() {
console.log(outerVar); // Работает
}
innerFunction();
}
outerFunction();
console.log(outerVar); // Ошибка: переменная не определена
Функция innerFunction
"видит" outerVar
, потому что объявлена внутри outerFunction
.
3. Область видимости и замыкания (Closures)
Если функция запоминает переменные из родительской области, даже после завершения её выполнения, это называется замыканием.
function createCounter() {
let count = 0;
return function () {
count++;
console.log(count);
};
}
const counter = createCounter();
counter(); // 1
counter(); // 2
Функция внутри замыкания "помнит" переменную count
, даже после завершения createCounter
.
4. Цепочка областей видимости (Scope Chain)
Если JavaScript не находит переменную в текущей области, он ищет её выше — в родительских областях.
let globalVar = "Я глобальная";
function firstFunction() {
let firstVar = "Я в первой функции";
function secondFunction() {
let secondVar = "Я во второй функции";
console.log(globalVar); // Найдено в глобальной области
console.log(firstVar); // Найдено в firstFunction
console.log(secondVar); // Найдено в secondFunction
}
secondFunction();
}
firstFunction();
Поиск идёт снизу вверх:
secondFunction
сначала ищется secondVar
→ найдена.firstVar
в firstFunction
→ найдена.globalVar
в глобальной области → найдена.Если переменной нет нигде, JavaScript выдаст ошибку.
5. Проблемы с областью видимости
5.1. Переменные var
выходят за блоки
if (true) {
var test = "test";
}
console.log(test); // "test", хотя ожидалась ошибка
Решение — использовать let
или const
.
5.2. Перезапись глобальных переменных
var message = "Привет";
function changeMessage() {
message = "Пока"; // Меняем глобальную переменную!
}
changeMessage();
console.log(message); // "Пока"
Решение — использовать let
и const
внутри функций.
6. Итог
- Глобальная область — переменные доступны везде (опасно!).
- Функциональная область — переменные доступны только внутри функции.
- Блочная область (
let
,const
) — переменные доступны только в{}
. - Лексическая область — функции "помнят" переменные, доступные при их создании.
- Цепочка областей видимости — поиск идёт снизу вверх.
- Замыкания позволяют функциям запоминать переменные из родительских областей.
Правильное управление областью видимости — залог чистого и предсказуемого кода.