# 04. Lexical Scope

Область видимости переменной - это те места в программе, где переменная доступна для использования (чтения/записи):

* Если переменная объявлена как верхнего уровня (глобальная), то её областью видимости является всё текущее окружение.
* Если переменная объявлена внутри модуля, то её области видимости является весь модуль.
* Если переменная объявлена внутри функции, то её областью видимости является функция.
* Если переменная объявлена как `let` или `const` и объявлена внутри блока кода, то областью видимости данной переменной будет данный блок кода (функция, или модуль).

В JS область видимости переменной определяется по её расположению в коде (это очевидно лексически), и вложенные функции имеют доступ к переменным, объявленным вовне. Этот механизм и называется **Lexical scoping** (область действия, ограниченная лексически).

```javascript
function fun() {
  const x = 5;
  function fun2() {
    console.log(x); // take x from outer scope
  }
}

function init() {
  var name = "Mozilla"; // name - локальная переменная, созданная в init
  function displayName() {
    // displayName() - внутренняя функция, замыкание
    alert(name); // displayName() использует переменную, объявленную в родительской функции
  }
  displayName();
}
init();
```

## Variable resolution

Каждый раз при обращении к переменной интерпретатору требуется её значение, то выполняется поиск её значения. Этот процесс называется **разрешением переменной** (variable resolution):

* Выполнить поиск определения `x` в ближайшем окружении.
* Если ближайшее окружение имеет свойство с именем `x`, то использовать его значение.
* Ближайшее окружение не имеет свойства с именем `x`, то продолжать поиск в следующем окружении в цепочке.
* Если второе окружение не имеет свойства с именем `x`, интерпретатор переходит к следующему объекту и т. д.
* Если ни один из объектов в цепочке областей видимости не имеет свойства с именем `x`, то интерпретатор считает, что переменная `x` находится вне области видимости данного программного кода и возбуждает ошибку `Reference Error`.
