Поиск по сайту
Ctrl + K
Вопросы по JS

Что такое область видимости (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) — переменные доступны только в {}.
    • Лексическая область — функции "помнят" переменные, доступные при их создании.
    • Цепочка областей видимости — поиск идёт снизу вверх.
    • Замыкания позволяют функциям запоминать переменные из родительских областей.

    Правильное управление областью видимости — залог чистого и предсказуемого кода.