W3docs

Область видимости переменных в JavaScript

Понимание области видимости переменных в JavaScript необходимо каждому разработчику. Руководство объясняет глобальную, функциональную и блочную области видимости.

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

Три вида областей видимости

JavaScript определяет видимость переменной исходя из места её объявления в исходном коде — это называется лексической (или статической) областью видимости. Существует три уровня:

  • Глобальная область видимости — объявлена за пределами любой функции или блока. Видима везде.
  • Функциональная область видимости — объявлена внутри функции. Видима только внутри этой функции (так работает var).
  • Блочная область видимости — объявлена с помощью let или const внутри блока { ... } (if, for или даже пустого {}). Видима только внутри этого блока.

Глобальная область видимости

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

javascript— editable

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

Функциональная область видимости

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

javascript— editable

Конструкция try...catch позволяет примеру продолжить выполнение, чтобы вы могли увидеть сообщение об ошибке, а не просто остановку скрипта.

Блочная область видимости

let и const ограничены ближайшим вмещающим блоком, а не всей функцией. Переменная, объявленная внутри блока if или for, перестаёт существовать после его завершения.

javascript— editable

Как вложенные функции видят внешние переменные

При вложении функций внутренняя функция может читать переменные из каждой окружающей её области видимости — своей собственной, области видимости внешней функции и глобальной области видимости. Эта цепочка доступных областей видимости называется лексическим окружением (или цепочкой областей видимости).

Когда JavaScript ищет имя, он начинает с текущей области видимости и двигается вовне, пока не найдёт переменную. Если поиск дошёл до глобальной области видимости без результата, возникает ReferenceError.

javascript— editable

Поиск идёт только наружу, но не внутрь — outer() не может видеть innerVar. Именно этот механизм лежит в основе замыканий: внутренняя функция сохраняет доступ к внешним переменным даже после того, как внешняя функция завершила выполнение.

var против let и const

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

javascript— editable

Классическая ловушка — цикл, создающий функции обратного вызова. С var существует одна общая переменная; с let каждая итерация получает собственную привязку:

javascript— editable

Подробнее о поведении var — включая поднятие и отсутствие блочной области видимости — читайте в разделе старый «var».

Поднятие и временная мёртвая зона

Объявления обрабатываются до выполнения кода. Объявление var поднимается и инициализируется значением undefined, поэтому обращение к нему до присваивания даёт undefined, а не ошибку. let и const тоже поднимаются, но остаются во временной мёртвой зоне (TDZ) — их нельзя использовать до строки, в которой они объявлены.

javascript— editable

Лучшие практики

  • Предпочитайте const, затем let, избегайте var. Блочная область видимости более предсказуема и предотвращает случайные утечки и ловушку с циклом и функциями обратного вызова, описанную выше.
  • Держите переменные в самой узкой подходящей области видимости. Объявляйте их внутри блока или функции, которые в них нуждаются, а не на верхнем уровне.
  • Минимизируйте глобальные переменные. Меньше глобальных переменных — меньше конфликтов имён и меньше значений, которые любой код может незаметно изменить.
  • Объявляйте перед использованием. Несмотря на существование поднятия, опираться на него делает код труднее для чтения.

Заключение

Область видимости определяет, где видима каждая переменная: глобально, в функции или в блоке. Вложенные функции формируют лексическое окружение, позволяющее внутреннему коду обращаться к внешним областям видимости через цепочку — основу замыканий. Выбор let/const вместо var обеспечивает надёжную блочную область видимости и позволяет избежать сюрпризов с поднятием. Далее изучите, как функции захватывают своё окружение, в разделе замыкания JavaScript, и как ведут себя возвращаемые функции в разделе функциональные выражения.

Практика

Практика
Какие виды области видимости переменных существуют в JavaScript?
Какие виды области видимости переменных существуют в JavaScript?
Was this page helpful?