JS
October 19, 2023

Области видимости в JavaScript (scope)

Объявленные переменные могут быть не доступны в разных частях кода. Их доступность определяется областью видимости.

Область видимости можно представить как коробку, в которой хранятся переменные. Переменные в коробке могут общаться друг с другом, и не могут общаться c переменными из соседних коробок.

Области видимости помогают:

  • Скрывать переменные от нежелательного доступа
  • Создавать независимые друг от друга блоки кода
  • Разбивать код на смысловые блоки

Области видимости

Глобальная

Переменная объявленная вне функции, блока или модуля попадает в глобальную область видимости, становясь доступной в любой части кода.

Глобально объявленные переменные попадают в объект window, например:

var a = '42'
window.a // 42

Блочная

Блочная область ограничивает видимость переменных фигурными скобками { }, например:

const a = 42 
console.log(a) // 42 

if (true) { 
  const b = 43 
  console.log(a) // 42 
  console.log(b) // 43 
}

console.log(b) // ReferenceError: Can't find variable: b

var не ограничивается блочной область видимости:

var a = 42 

if (true)  var a = 43

console.log(a) // 43

Функциональная

Функциональная область ограничивает видимость переменных телом функции, независимо от того, с помощью какого ключевого слова они объявлены — var, const или let.

const a = 42
var b = 44

function scoped() {
  const a = 43
  var b = 45
}

console.log(a) // 42
console.log(b) // Reference error.

Функции создают собственные области видимости, которые не пересекаются, поэтому в этом случае ошибки не будет:

function scope1() {
  const a = 42
}

function scope2() {
  const a = 43
}

Функциям так же доступны переменные только из родительской области видимости:

function outer() {
  const a = 42

  function inner() {
    console.log(a) // 42
  }
}

Такое поведение называется наследованием областей видимости.

Модульная

ES6 Модули также создают область видимости для переменных, функций и классов.

// область видимости модуля circle 

const pi = 3.14 
console.log(pi) // 3.14
import './circle' 
console.log(pi) // ReferenceError

Поднятие (hoisting)

Поднятие — это термин, описывающий подъем переменной или функции в глобальную или функциональную области видимости.

Поднимаются только функциональные выражения и переменные, объявленные с помощью ключевого слова var. Обычные функции и стрелочные функции, а также переменные, объявленные с помощью ключевых слов let и const не поднимаются.

Дополнительно

https://developer.mozilla.org/ru/docs/Glossary/Hoisting