В этом руководстве вы узнаете об области видимости переменных JavaScript, которая определяет доступность переменных.
JavaScript имеет три области видимости:
- Глобальная область
- Локальная область
- Область действия блока (начиная с ES6)
Глобальная область
Когда механизм JavaScript выполняет сценарий, он создает глобальный контекст выполнения.
Кроме того, он также назначает переменные, которые вы объявляете вне функций, глобальному контексту выполнения. Эти переменные находятся в глобальной области видимости. Они также известны как глобальные переменные.
Пример:
var message = 'Hi';
message переменной имеет глобальную область действия. Он может быть доступен везде в сценарии.

Локальная область
Переменные, которые вы объявляете внутри функции, являются локальными для этой функции. Они называются локальными переменными. Например:
var message = 'Hi';
function say() {
var message = 'Hello';
console.log('message');
}
say();
console.log(message);
Выход:
Hello Hi
Когда движок JavaScript выполняет функцию say(), он создает контекст выполнения функции. Переменное message объявленное внутри функции say(), привязано к контексту выполнения функции, а не к глобальному контексту выполнения.

Цепочка областей
Рассмотрим следующий пример:
var message = 'Hi';
function say() {
console.log(message);
}
say();
Выход:
Hi
В этом примере мы ссылаемся на переменную message внутри функции say(). JavaScript выполняет следующие действия:
- Находит
messageпеременной в текущем контексте (контексте выполнения функции) функцииsay(). Он не может найти ни одного. - Находит переменную
messageво внешнем контексте выполнения, который является глобальным контекстом выполнения. Он находит переменнуюmessage.
Способ, которым JavaScript разрешает переменную, заключается в просмотре ее в ее текущей области видимости. Если он не может найти переменную, он переходит к внешней области видимости, которая называется цепочкой областей видимости.

Дополнительный пример
Рассмотрим следующий пример:
var y = 20;
function bar() {
var y = 200;
function baz() {
console.log(y);
}
baz();
}
bar();
Выход:
200
В этом примере:
- Сначала движок JavaScript находит переменную y в области видимости функции
baz(). Он не может найти ни одного. Так что это выходит за рамки этого. - Затем движок JavaScript находит переменную y в функции
bar(). Он может найти переменную y в области действия функцииbar()и прекратить поиск.
Утечки глобальных переменных
Пример:
function getCounter() {
counter = 10;
return counter;
}
console.log(getCounter());Выход:
10
В этом примере мы присвоили переменной counter значение 10 без ключевых слов var, let или const, а затем вернули его.
Вне функции мы вызвали функцию getCounter() и показали результат в консоли.
Эта проблема известна как утечка глобальных переменных.
Под капотом движок JavaScript сначала ищет переменную counter в локальной области видимости функции getCounter(). Поскольку ключевое слово var, let или const отсутствует, переменная counter недоступна в локальной области. Он не создан.
Затем движок JavaScript следует по цепочке областей видимости и ищет переменную counter в глобальной области видимости. Глобальная область также не имеет переменной counter, поэтому механизм JavaScript создает переменную counter в глобальной области.
Чтобы исправить это «странное» поведение, вы используете 'use strict' в верхней части скрипта или в верхней части функции:
'use strict'
function getCounter() {
counter = 10;
return counter;
}
console.log(getCounter());Теперь код выдает ошибку:
ReferenceError: counter is not defined
Ниже показано, как использовать 'use strict' в функции:
function getCounter() {
'use strict'
counter = 10;
return counter;
}
console.log(getCounter());Область блока
ES6 предоставляет ключевые слова let и const, которые позволяют объявлять переменные в области блока.
Как правило, всякий раз, когда вы видите фигурные скобки {}, это блок. Это может быть область внутри циклов if, else, switch или for, do while и while.
См. следующий пример:
function say(message) {
if(!message) {
let greeting = 'Hello'; // block scope
console.log(greeting);
}
// say it again ?
console.log(greeting); // ReferenceError
}
say();В этом примере мы ссылаемся на переменную greeting вне блока if, что приводит к ошибке.
