Что такое область видимости JavaScript?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое область видимости JavaScript
Область видимости (scope) определяет, где в коде переменная доступна. Это один из фундаментальных концептов JavaScript, влияющий на поведение переменных и функций. Правильное понимание scope критично для написания безошибочного кода.
Типы областей видимости
1. Глобальная область видимости (Global Scope)
Переменные, объявленные вне всех функций, доступны везде:
var globalVar = "я глобальная";
let globalLet = "я тоже глобальная";
const globalConst = "и я";
function myFunction() {
console.log(globalVar); // "я глобальная"
}
myFunction(); // работает
console.log(globalVar); // работает
В браузере глобальные переменные попадают в объект window:
var name = "John";
console.log(window.name); // "John"
// let и const не попадают в window
let secret = "hidden";
console.log(window.secret); // undefined
2. Функциональная область видимости (Function Scope)
Переменные, объявленные внутри функции, видны только в этой функции:
function greet() {
var message = "Hello"; // видна только в greet
console.log(message); // "Hello"
}
greet();
console.log(message); // ReferenceError: message is not defined
Это относится к var, let и const, но они работают по-разному.
3. Блочная область видимости (Block Scope)
let и const имеют блочную область видимости, а var — функциональную:
if (true) {
var x = 1;
let y = 2;
const z = 3;
}
console.log(x); // 1 (var игнорирует блоки)
console.log(y); // ReferenceError: y is not defined
console.log(z); // ReferenceError: z is not defined
Блоки включают: if, for, while, switch, try/catch
for (let i = 0; i < 3; i++) {
// i видна только в этом блоке
}
console.log(i); // ReferenceError
for (var j = 0; j < 3; j++) {
// j видна всюду в функции
}
console.log(j); // 3
4. Лексическая область видимости (Lexical Scope)
Функция имеет доступ к переменным из области видимости, где она была объявлена, не где вызывается:
const outer = "внешняя";
function outer_function() {
const local = "локальная";
function inner() {
console.log(outer); // "внешняя" (доступна из лексического контекста)
console.log(local); // "локальная"
}
return inner;
}
const fn = outer_function();
fn(); // работает, хотя вызов вне функции
Цепочка областей видимости (Scope Chain)
Когда переменная не найдена в текущей области, JavaScript ищет её в родительской, и так вверх до глобальной:
const level1 = "1-я уровень";
function level2() {
const level2_var = "2-й уровень";
function level3() {
const level3_var = "3-й уровень";
console.log(level1); // найдена в глобальной
console.log(level2_var); // найдена в level2
console.log(level3_var); // найдена в level3
}
level3();
}
level2();
Замыкания (Closures)
Замыкание — это когда функция имеет доступ к переменным из своей лексической области видимости, даже после того, как внешняя функция вернула значение:
function createCounter() {
let count = 0; // приватная переменная
return function() {
return ++count; // имеет доступ к count
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
// count недоступна снаружи — инкапсуляция!
console.log(count); // ReferenceError
var vs let vs const
// var: функциональная область видимости, переподнимается
function testVar() {
if (true) {
var x = 1;
}
console.log(x); // 1 (видна вне блока!)
}
// let: блочная область видимости
function testLet() {
if (true) {
let y = 2;
}
console.log(y); // ReferenceError
}
// const: блочная область видимости, неизменяемая
function testConst() {
if (true) {
const z = 3;
}
console.log(z); // ReferenceError
}
Hoisting (Подъём переменных)
var поднимается с инициализацией undefined:
console.log(x); // undefined (не ошибка!)
var x = 5;
console.log(x); // 5
// То же самое, что:
var x;
console.log(x); // undefined
x = 5;
let и const поднимаются, но не инициализируются (Temporal Dead Zone):
console.log(y); // ReferenceError!
let y = 5;
Практические примеры
Опасность глобальных переменных:
var counter = 0;
function increment() {
counter++;
}
// Где-то в другом файле...
var counter = 100; // перезаписали!
Правильно с замыканием:
const makeCounter = () => {
let counter = 0; // приватная
return {
increment: () => ++counter,
get: () => counter,
reset: () => (counter = 0)
};
};
const counter = makeCounter();
console.log(counter.increment()); // 1
console.log(counter.get()); // 1
Ключевые выводы
- Используй
letиconstвместоvar letиconstимеют блочную область видимости- Функции создают свою область видимости
- Замыкания дают доступ к переменным внешней области
- Scope chain — механизм поиска переменных вверх по цепочке
- Приватные переменные можно создавать через замыкания
Понимание scope — основа для написания предсказуемого и безопасного кода.