--- sidebar_position: 6 --- # Область видимости переменных, замыкание Источник: DeepSeek Доп. источник: [https://learn.javascript.ru/closure](https://learn.javascript.ru/closure) ## Область видимости (scope) В JavaScript **область видимости (scope)** определяет, где переменные, функции и другие идентификаторы могут быть использованы в коде. Понимание области видимости важно для написания корректного и предсказуемого кода. В JavaScript есть несколько типов областей видимости: 1. **Глобальная область видимости (Global Scope)** \ Переменные, объявленные вне всех функций или блоков, находятся в глобальной области видимости. Они доступны из любого места в коде. 2. **Локальная область видимости (Function Scope)** \ Переменные, объявленные внутри функции, доступны только внутри этой функции. Это называется function scope. 3. **Блочная область видимости (Block Scope)** \ С появлением let и const в ES6 появилась блочная область видимости. Переменные, объявленные внутри блока (например, внутри {}), доступны только внутри этого блока. \ Обратите внимание, что var не имеет блочной области видимости 4. **Лексическая область видимости (Lexical Scope)** \ JavaScript использует лексическую (статическую) область видимости. Это означает, что область видимости определяется во время написания кода, а не во время выполнения. Вложенные функции имеют доступ к переменным из внешних функций. 5. **Область видимости модулей (Module Scope)** В ES6 появились модули, которые имеют свою собственную область видимости. Переменные, объявленные в модуле, не доступны извне, если они не экспортированы. 6. **Цепочка областей видимости (Scope Chain)** Когда JavaScript ищет переменную, он сначала проверяет текущую область видимости, затем переходит к внешним областям, пока не достигнет глобальной области. Если переменная не найдена, возникает ошибка. 7. **Замыкания (Closures)** Замыкание — это функция, которая запоминает свое лексическое окружение даже после того, как внешняя функция завершила выполнение. Это возможно благодаря области видимости. - **Глобальная область видимости:** переменные доступны везде. - **Локальная (function scope):** переменные доступны только внутри функции. - **Блочная (block scope):** переменные доступны только внутри блока ({}), если объявлены через let или const. - **Лексическая область видимости:** вложенные функции имеют доступ к переменным из внешних функций. - **Модульная область видимости:** переменные в модулях изолированы. ## Замыкание (closure) **Замыкание (closure)** в JavaScript — это мощный механизм, который позволяет функциям "запоминать" свое лексическое окружение (область видимости), даже после того, как внешняя функция завершила выполнение. Замыкания часто используются для создания приватных переменных, реализации функций высшего порядка и других паттернов программирования. ### Как работает замыкание? Когда функция создается, она запоминает ссылку на свое лексическое окружение (все переменные, которые были доступны в момент ее создания). Даже если внешняя функция завершила выполнение, внутренняя функция сохраняет доступ к переменным из этого окружения. ### Пример замыкания ```js function outer() { let outerVar = "Я из внешней функции"; function inner() { console.log(outerVar); // Используем переменную из внешней функции } return inner; } const closureFunc = outer(); // outer завершила выполнение closureFunc(); // "Я из внешней функции" — inner помнит outerVar ``` Здесь: 1. Функция `outer` создает переменную `outerVar`. 2. Функция `inner` использует эту переменную. 3. Когда outer завершает выполнение, она возвращает `inner`. 4. Переменная `closureFunc` теперь содержит функцию `inner`, которая сохраняет доступ к `outerVar`. ### Почему это работает? JavaScript использует **лексическую область видимости (lexical scoping)**. Это означает, что область видимости функции определяется в момент ее создания, а не в момент вызова. Внутренняя функция (`inner`) "замыкается" на переменные из внешней функции (`outer`), даже если внешняя функция уже завершила выполнение. ### Практическое применение замыканий 1. **Приватные переменные** \ Замыкания позволяют создавать приватные переменные, которые недоступны извне. ```js function createCounter() { let count = 0; // Приватная переменная return function() { count++; return count; }; } const counter = createCounter(); console.log(counter()); // 1 console.log(counter()); // 2 console.log(counter()); // 3 ``` Здесь переменная `count` недоступна извне, но функция-счетчик может изменять и возвращать ее значение. 2. **Функции высшего порядка** \ Замыкания часто используются в функциях высшего порядка, таких как `map`, `filter`, `reduce`. ```js function createMultiplier(multiplier) { return function(number) { return number * multiplier; }; } const double = createMultiplier(2); console.log(double(5)); // 10 ``` Здесь `createMultiplier` возвращает функцию, которая "запоминает" значение `multiplier`. 3. **Модули и инкапсуляция** \ Замыкания позволяют создавать модули с приватными методами и переменными. ```js const module = (function() { let privateVar = "Я приватная"; function privateMethod() { console.log(privateVar); } return { publicMethod: function() { privateMethod(); } }; })(); module.publicMethod(); // "Я приватная" console.log(module.privateVar); // undefined (недоступно) ``` 4. **Колбэки и асинхронный код** \ Замыкания часто используются в асинхронном коде, чтобы сохранить состояние. Здесь функция внутри setTimeout "запоминает" значение name. ```js function delayedGreeting(name) { setTimeout(function() { console.log(`Привет, ${name}!`); }, 1000); } delayedGreeting("Алексей"); // Через 1 секунду: "Привет, Алексей!" ``` Здесь функция внутри setTimeout "запоминает" значение name. ### Как избежать утечек памяти? Замыкания могут приводить к утечкам памяти, если они сохраняют ссылки на большие объекты, которые больше не используются. Чтобы избежать этого: - Убедитесь, что замыкания не сохраняют ненужные данные. - Используйте null для очистки ссылок, когда они больше не нужны.