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

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Область видимости (или scope) в JS – это как "зона доступа" 🚧 для переменных и функций. Если переменная объявлена глобально 🌍, её видно везде. Локально 🏠 – только внутри функции. А блочная видимость 📦 ограничивает доступ внутри блоков кода, например, внутри циклов или условий.

Область видимости решает проблему хаоса в коде. Без неё, все переменные были бы доступны везде, что приводило бы к ошибкам и конфликтам. Это как если бы в большом доме все ключи подходили ко всем дверям 🚪🔑 – слишком легко запутаться или что-то потерять.

Это упрощает написание программ, делая код более читаемым и безопасным. Понимание scope помогает контролировать, где и как используются данные, предотвращая неожиданные "сюрпризы" 🎁 в поведении программы.

Пример

Давайте представим, что вы пишете программу для учёта расходов за месяц. Ваша программа позволяет пользователю добавлять расходы по разным категориям: еда, транспорт, развлечения и так далее. Для этого вы решили использовать переменные для хранения общей суммы расходов по каждой категории.

Python
Скопировать код
total_expenses = 0 # Общие расходы

def add_expense(category, amount):
    if category == "еда":
        food_expenses = 0
        food_expenses += amount
        print(f"Расходы на еду: {food_expenses}")
    elif category == "транспорт":
        transport_expenses = 0
        transport_expenses += amount
        print(f"Расходы на транспорт: {transport_expenses}")
    # И так далее для других категорий
    
    global total_expenses
    total_expenses += amount
    print(f"Общие расходы: {total_expenses}")

add_expense("еда", 500)
add_expense("транспорт", 300)

🤔 Но здесь есть проблема: каждый раз, когда вы вызываете функцию add_expense, переменные food_expenses и transport_expenses создаются заново и их значения сбрасываются. Это происходит потому, что эти переменные находятся в локальной области видимости функции add_expense и не сохраняют своё значение между вызовами.

🔍 Решение: чтобы сохранять значения расходов между вызовами функции, нужно объявить переменные food_expenses и transport_expenses в глобальной области видимости, аналогично переменной total_expenses.

Python
Скопировать код
total_expenses = 0 # Общие расходы
food_expenses = 0 # Расходы на еду
transport_expenses = 0 # Расходы на транспорт

def add_expense(category, amount):
    global food_expenses, transport_expenses, total_expenses
    
    if category == "еда":
        food_expenses += amount
        print(f"Расходы на еду: {food_expenses}")
    elif category == "транспорт":
        transport_expenses += amount
        print(f"Расходы на транспорт: {transport_expenses}")
    
    total_expenses += amount
    print(f"Общие расходы: {total_expenses}")

add_expense("еда", 500)
add_expense("транспорт", 300)

Теперь, благодаря глобальной области видимости переменных, программа корректно учитывает и сохраняет расходы по каждой категории между вызовами функции add_expense. Этот пример показывает, как важно понимать области видимости переменных, чтобы правильно организовать хранение и доступ к данным в вашей программе.

Кинга Идем в IT: пошаговый план для смены профессии

Всё, что нужно знать о глобальной и локальной области видимости

Глобальная и локальная область видимости – это два основных типа области видимости в JavaScript. Глобальные переменные объявляются вне всех функций и доступны отовсюду в коде. Это значит, что они могут быть использованы и изменены в любом месте программы. С другой стороны, локальные переменные объявляются внутри функций и доступны только в пределах этих функций. Это помогает избегать конфликтов имен и делает код более безопасным и предсказуемым.

Пример глобальной переменной:

JS
Скопировать код
var globalVar = "Я глобальная переменная";

function testScope() {
    console.log(globalVar); // Вывод: "Я глобальная переменная"
}

testScope();
console.log(globalVar); // Вывод: "Я глобальная переменная"

Пример локальной переменной:

JS
Скопировать код
function testScope() {
    var localVar = "Я локальная переменная";
    console.log(localVar); // Вывод: "Я локальная переменная"
}

testScope();
// console.log(localVar); // Ошибка: localVar is not defined

Лексическая область видимости и сила замыканий

Лексическая область видимости означает, что доступность переменных определяется их физическим расположением в коде. Это позволяет внутренним функциям иметь доступ к переменным внешних функций. Замыкания – это функции, которые запоминают и имеют доступ к переменным из своей лексической области видимости, даже после того, как внешняя функция была завершена.

Пример замыкания:

JS
Скопировать код
function outerFunction() {
    var outerVar = "Я внешняя переменная";

    function innerFunction() {
        console.log(outerVar); // Вывод: "Я внешняя переменная"
    }

    return innerFunction;
}

var myInnerFunction = outerFunction();
myInnerFunction();

Блочная область видимости и ключевые слова let и const

Блочная область видимости в JavaScript вводится с помощью ключевых слов let и const. Эти переменные доступны только внутри блока (например, внутри цикла или условного оператора), в котором они были объявлены. Это предотвращает множество ошибок и делает код более читаемым и безопасным.

Пример блочной области видимости:

JS
Скопировать код
if (true) {
    let blockScopedVar = "Я переменная с блочной областью видимости";
    console.log(blockScopedVar); // Вывод: "Я переменная с блочной областью видимости"
}

// console.log(blockScopedVar); // Ошибка: blockScopedVar is not defined

Динамическая область видимости и методы изменения контекста

В отличие от лексической, динамическая область видимости в JavaScript зависит не от местоположения переменной в коде, а от контекста её вызова. Это поведение чаще всего связано с ключевым словом this и методами .call(), .apply(), и .bind(), которые позволяют изменять контекст this для функций.

Пример изменения контекста с помощью .bind():

JS
Скопировать код
var person = {
    name: "Алексей",
    greet: function() {
        console.log("Привет, меня зовут " + this.name);
    }
};

var greetPerson = person.greet.bind(person);
greetPerson(); // Вывод: "Привет, меня зовут Алексей"

Понимание области видимости в JavaScript – ключ к написанию эффективного и безопасного кода. Это позволяет избегать конфликтов имен, упрощает отладку и помогает создавать более модульные и масштабируемые приложения.

Свежие материалы