# Розділ 8.Область видимості

&#x20;    У **JS** існує така річ як **інтерпретатор** - інструмент, який читає рядки коду по порядку. Так ось **інтерпретатор**  бачить код по своєму :

```javascript
'use strict';

var a = 5;
```

&#x20;    Ось так код виглядає після компіляції:

```javascript
'use strict';

var a;  // ініціалізація змінної

a = 5;  // присвоювання значення
```

&#x20;    Першочерговим здійснюється пошук усіх проініціалізованих змінних, потім пошук усіх функцій, потім вже присвоювання.

&#x20;    Також у **JS** існує такий невидимий об'єкт як **Lexical Environment** - суть його роботи полягає у формуванні глобального об'єкта всіх змінних та функцій:

```javascript
'use strict';

// Lexical Environment {a : undefined}    - знайдено "а", проте невідоме значення

var a = 5;

// Lexical Environment {a : 5}    - знайдено "а", значення "5" 
// Значеня стало відомим після проходження інтерпритатором рядка з присвоєнням
```

&#x20;    Ми з Вами знаємо два основних види функції :

```javascript
'use strict';

// Function Declaration
function test1() {};

//Function Expression
var test2 = function() {};
```

&#x20;    Так ось основним **недоліком Function Expression** є те, що ми можемо її виконати лише після знаку присвоєння, бо до цього часу **Lexical Environment** не має інформації про те що вона існує:

```javascript
'use strict';

// Lexical Environment {test : undefined}

test(); // не виконається, бо ще не відомо значення 

var test = function() {};

// Lexical Environment {test : function}

test(); // виконається
```

&#x20;    Ми з Вами для ініціалізації змінної завжди використовували **var**, проте існує ще два способи це зробити:

```javascript
'use strict';

var a = 5;

let b = 6;

const C = 7;
```

&#x20;    **var** - використовується для створення змінної, яку видно глобально:

```javascript
'use strict';

var a = 0;

console.log(a); // 0

if (true) {
    var a = 7;
    console.log(a); // 7
};

console.log(a); // 7
```

&#x20;    **let** - використовується для створення змінної, яку видно в певних межах (як правило лише у фігурних дужках):

```javascript
'use strict';

let a = 0;

console.log(a); // 0

if (true) {
    let a = 7;
    console.log(a); // 7
};

console.log(a); // 0
```

&#x20;    **const** -  використовується для створення змінної, яку не можна змінити - називається константою і як правило назва пишеться великими буквами:

```javascript
'use strict';

const A = 0;

console.log(A); // 0

A = 9; // виникне помилка так як не можна змінювати константи
```

&#x20;    Проте якщо константою є масив чи об'єкт - то **внутрішні значення** **можуть змінюватись**:

```javascript
'use strict';

const A = {
    age: 2
};

console.log(A.age); // 2

A.age = 9; 

console.log(A.age); // 9
```

&#x20;    **JS** код найкраще розглядати у вигляді коробок. Представимо ситуацію, що у Вас є коробка 1, а в ній коробка 2. І Ви вирішили шукати олівець у коробці 2, якщо його там не має, то пошук здійснюватиметься на рівень вище - у коробці 1 :

```javascript
'use strict';

function box1 () {
    var pencil = 1;            // 2. Створити олівця
    
    function box2() {
        console.log(pencil);   // 4. Відобразити олівця
    }
    
    box2();                    // 3. Виконати функцію box2
}

box1();                        // 1. Виконати функцію box1


// Так як олівця немає у box2 - здійснюватиметься пошук на рівень вище
```

&#x20;    Чому варто використовувати **let**, a не **var** - тому, що **let** після того як буде не потрібна - буде видалятись з пам'яті, а отже код буде легшим та й основний недолік глобалізації даних в тому, що на них може вплинути любе середовище, а отже можуть виникати неконтрольовані зміни. Тому надалі ми в коді будемо використовувати **лише let** та **const**.

&#x20;    Отож ми дізнались, що існує **інтерпретатор**, який читає код по порядку, після компіляції формує власний код, що для контролю змінних та функцій було створено невидимий об'єкт **Lexical Environment**, основна задача якого тримати стан змінних і також крім **var** для ініціалізації можна використовувати більш точні і оптимальніші **let** та **const**. У наступному розділі ми детальніше розглянемо з Вами що ж таке об'єкт.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://angularlessons.gitbook.io/javascriptiseasy/rozdil-8.oblast-vidimosti.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
