You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/06-advanced-functions/03-closure/article.md
+16-16Lines changed: 16 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,17 +5,17 @@ JavaScript -- це дуже функціонально орієнтована м
5
5
6
6
Ми вже знаємо, що функція може отримати доступ до змінних з зовнішнього середовища (зовнішні змінні).
7
7
8
-
Але що станеться, якщо зовнішні змінні змінюються після створення функції? Чи отримає функція нові значення чи старі?
8
+
Але що станеться, якщо зовнішні змінні зміняться після створення функції? Функція отримає нові значення чи старі?
9
9
10
10
А що буде, коли функція передається як параметр і викликається з іншого місця коду, чи отримає вона доступ до зовнішніх змінних на новому місці?
11
11
12
12
Давайте розширимо наші знання, щоб зрозуміти ці та більш складні сценарії.
13
13
14
14
```smart header="Тут ми поговоримо про змінні `let/const`"
15
-
У JavaScript існує 3 способи оголошення змінної: `let`, `const` (сучасні способи) та `var` (залишок минулого).
15
+
У JavaScript існує 3 способи оголошення змінної: `let`, `const` (сучасні способи) та `var` (застарілий).
16
16
17
17
- У цій статті ми будемо використовувати `let` для змінних у прикладах.
18
-
- Змінні, оголошені через `const`, поводяться так само, тому ця стаття також стосується `const`.
18
+
- Змінні, оголошені через `const`, в цих аспектах поводяться так само, тому ця стаття також стосується `const`.
19
19
-`var` має деякі помітні відмінності, вони будуть розглянуті в статті <info:var>.
20
20
```
21
21
@@ -29,15 +29,15 @@ JavaScript -- це дуже функціонально орієнтована м
29
29
{
30
30
// тут виконується певна робота з локальними змінними, яку не слід бачити зовні
31
31
32
-
let message = "Привіт"; // змінна видима тільки у цьому блоці
32
+
let message = "Привіт"; // змінна, яка буде видима тільки у цьому блоці
33
33
34
34
alert(message); // Привіт
35
35
}
36
36
37
-
alert(message); // Помилка: змінну message не було оголошено
37
+
alert(message); // ReferenceError: message is not defined
38
38
```
39
39
40
-
Ми можемо використовувати це, щоб виділити фрагмент коду, який працює зі змінними, які доступні лише з нього:
40
+
Ми можемо використовувати це, щоб ізолювати фрагмент коду разом із змінними, які стосуються лише його:
41
41
42
42
```js run
43
43
{
@@ -78,7 +78,7 @@ if (true) {
78
78
alert(phrase); // Привіт!
79
79
}
80
80
81
-
alert(phrase); // Помилка, такої змінної немає!
81
+
alert(phrase); // Помилка, за межами if такої змінної немає!
82
82
```
83
83
84
84
Тут, після завершення `if`, `alert` нижче не побачить `phrase`, отже, помилка.
@@ -100,7 +100,7 @@ alert(i); // Помилка, такої змінної немає
100
100
101
101
## Вкладені функції
102
102
103
-
Функція називається "вкладеною", коли вона створюється всередині іншої функції.
103
+
Функція називається "вкладеною" (з англ. nested), коли вона створюється всередині іншої функції.
104
104
105
105
З JavaScript це зробити дуже легко.
106
106
@@ -164,10 +164,10 @@ alert( counter() ); // 2
164
164
165
165
Об’єкт лексичного середовища складається з двох частин:
166
166
167
-
1.*Запис середовища (Environment Record)* -- об’єкт, який зберігає всі локальні змінні як властивості (та деяку іншу інформацію, наприклад значення `this`).
167
+
1.*Запис середовища (Environment Record)* -- об’єкт, який зберігає всі локальні змінні в якості своїх властивостей (та деяку іншу інформацію, наприклад значення `this`).
168
168
2. Посилання на *зовнішнє лексичне середовище*, яке пов’язане із зовнішнім кодом.
169
169
170
-
**"Змінна" це лише властивість спеціального внутрішнього об’єкта, `Запис середовища (Environment Record)`. "Отримати або змінити змінну" насправді означає "отримати або змінити властивість цього об’єкта".**
170
+
**"Змінна" це лише властивість спеціального внутрішнього об’єкта, `Запис середовища (Environment Record)`. "Отримати або змінити змінну" означає "отримати або змінити властивість цього об’єкта".**
171
171
172
172
У цьому простому коді без функцій є лише одне лексичне середовище:
173
173
@@ -199,12 +199,12 @@ alert( counter() ); // 2
199
199
```smart header="Лексичне середовище -- це об'єкт специфікації"
200
200
"Лексичне середовище" -- це об’єкт специфікації: він існує лише "теоретично" в [специфікації мови](https://tc39.es/ecma262/#sec-lexical-environments) щоб показати, як все працює. Ми не можемо отримати цей об’єкт у нашому коді та керувати ним безпосередньо.
201
201
202
-
Рушії JavaScript також можуть його оптимізувати, відкидати змінні, які не використовуються для економії пам’яті та виконувати інші внутрішні трюки, доки видима поведінка залишається такою, як описано у специфікації.
202
+
Також рушії JavaScript можуть його оптимізовувати, відкидати змінні, які не використовуються для економії пам’яті та виконувати інші внутрішні трюки, доки видима поведінка залишається такою, як описано у специфікації.
203
203
```
204
204
205
205
### 2 етап. Функції створені як Function Declarations
206
206
207
-
Функція також є значенням, як і значення у змінних.
207
+
Функція також є значенням, як і значення всередині змінних.
208
208
209
209
**Різниця в тому, що функція створена за допомогою Function Declaration, ініціалізується миттєво і повністю.**
210
210
@@ -246,12 +246,12 @@ alert( counter() ); // 2
246
246
247
247
**Коли код хоче отримати доступ до змінної -- спочатку шукає її у внутрішньому лексичному середовищі, потім у зовнішньому, потім у зовнішньому до попереднього і так далі поки не дійде до глобального.**
248
248
249
-
Якщо змінна ніде не знайдена, то буде помилка для увімкненого суворого режиму (без `use strict`, присвоєння неіснуючої змінної створює нову глобальну змінну для сумісності зі старим кодом).
249
+
Якщо змінна ніде не знайдена, то при `"use strict"` буде помилка (без `use strict` присвоєння неіснуючої змінної створює нову глобальну змінну для сумісності зі старим кодом).
250
250
251
251
У цьому прикладі пошук відбувається наступним чином:
252
252
253
253
- Для змінної `name`, `alert` у функції `say` знаходить її негайно у внутрішньому лексичному середовищі.
254
-
- Коли він хоче отримати доступ до `phrase`, він спочатку шукає її серед локальних змінних, де її немає, і врешті решт іде за посиланням на зовнішнє лексичне середовище і знаходить її там.
254
+
- Коли вона хоче отримати доступ до `phrase`, вона спочатку шукає її серед локальних змінних, де її немає, і врешті решт іде за посиланням на зовнішнє лексичне середовище і знаходить її там.
Різниця полягає в тому, що під час виконання `makeCounter()`, крихітна вкладена функція створюється, яка складається лише з одного рядка: `return count++`. Ми не запускаємо її, лише створюємо.
281
+
Різниця полягає в тому, що під час виконання `makeCounter()`, створюється крихітна вкладена функція, яка складається лише з одного рядка: `return count++`. Ми не запускаємо її, лише створюємо.
282
282
283
283
Усі функції пам’ятають лексичне середовище, в якому вони були створені. Технічно тут немає ніякої магії: усі функції мають приховану властивість з назвою `[[Environment]]`, що зберігає посилання на лексичне середовище, де була створена функція:
284
284
@@ -371,7 +371,7 @@ g = null; // ...і тепер пам’ять очищена
371
371
372
372
Але на практиці рушії JavaScript намагаються оптимізувати це. Вони аналізують використання змінних, і якщо з коду очевидно, що зовнішня змінна не використовується -- вона видаляється.
373
373
374
-
**Важливим побічним ефектом у рушію V8 (Chrome, Edge, Opera) є те, що така змінна стане недоступною під час налагодження.**
374
+
**Важливим побічним ефектом у рушія V8 (Chrome, Edge, Opera) є те, що така змінна стане недоступною під час налагодження.**
375
375
376
376
Спробуйте запустити наведений нижче приклад у Chrome із відкритими інструментами розробника.
0 commit comments