← Назад к вопросам

Что такое область видимости JavaScript?

1.3 Junior🔥 271 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое область видимости 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 — основа для написания предсказуемого и безопасного кода.