From 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:43:23 -0500 Subject: initial commit --- .../javascript/reference/statements/let/index.html | 272 +++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 files/uk/web/javascript/reference/statements/let/index.html (limited to 'files/uk/web/javascript/reference/statements/let/index.html') diff --git a/files/uk/web/javascript/reference/statements/let/index.html b/files/uk/web/javascript/reference/statements/let/index.html new file mode 100644 index 0000000000..ee0db303e6 --- /dev/null +++ b/files/uk/web/javascript/reference/statements/let/index.html @@ -0,0 +1,272 @@ +--- +title: let +slug: Web/JavaScript/Reference/Statements/let +tags: + - ECMAScript 2015 + - JavaScript + - let + - змінні +translation_of: Web/JavaScript/Reference/Statements/let +--- +
{{jsSidebar("Statements")}}
+ +

Оператор let оголошує локальну змінну блочної області видимості, з необов'язковим присвоєнням їй початкового значення.

+ +
{{EmbedInteractiveExample("pages/js/statement-let.html")}}
+ + + +

Синтаксис

+ +
let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN];
+ +

Параметри

+ +
+
var1, var2, …, varN
+
Імена змінної або змінних, що оголошуються. Кожне ім'я має бути дозволеним ідентифікатором JavaScript.
+
value1, value2, …, valueN {{optional_inline}}
+
Для кожної оголошеної змінної ви можете вказати її початкове значення будь-яким дозволеним виразом JavaScript.
+
+ +

Опис

+ +

Оператор let дозволяє оголошувати змінні, що обмежені областю видимості {{jsxref("statements/block", "блоку")}} або виразу, для якого використовуються, на відміну від ключового слова {{jsxref("statements/var", "var")}}, яке визначає змінну глобально, чи локально для всієї функції, незалежно від області видимості блоку. Інша відмінність між операторами {{jsxref("statements/var", "var")}} та let полягає в тому, що останній ініціалізується тільки після оцінювання синтаксичним аналізатором (дивіться нижче).

+ +

Як і {{jsxref("statements/const", "const", "Description")}}, let не створює властивостей об'єкта {{domxref('window')}} при глобальному оголошенні (у області видимості верхнього рівня).

+ +

Пояснення, чому була обрана назва "let" можна подивитись тут.

+ +

Правила області видимості

+ +

Областю видимості змінних, оголошених через let, є блок, у якому вони визначені, а також будь-які вкладені в нього блоки. У цьому сенсі let дуже схожий на var. Головна відмінність полягає в тому, що областю видимості змінної var є уся замикаюча функція:

+ +
function varTest() {
+  var x = 1;
+  {
+    var x = 2;  // та сама змінна!
+    console.log(x);  // 2
+  }
+  console.log(x);  // 2
+}
+
+function letTest() {
+  let x = 1;
+  {
+    let x = 2;  // інша змінна
+    console.log(x);  // 2
+  }
+  console.log(x);  // 1
+}
+
+ +

На верхньому рівні програм та функцій let, на відміну від var, не створює властивості глобального об'єкта. Наприклад:

+ +
var x = 'глобальна';
+let y = 'глобальна';
+console.log(this.x); // "глобальна"
+console.log(this.y); // undefined
+
+ +

Імітація приватних членів

+ +

Працюючи з конструкторами, можна використовувати let-зв'язування для створення приватних членів без використання замикань:

+ +
var Thing;
+
+{
+  let privateScope = new WeakMap();
+  let counter = 0;
+
+  Thing = function() {
+    this.someProperty = 'foo';
+
+    privateScope.set(this, {
+      hidden: ++counter,
+    });
+  };
+
+  Thing.prototype.showPublic = function() {
+    return this.someProperty;
+  };
+
+  Thing.prototype.showPrivate = function() {
+    return privateScope.get(this).hidden;
+  };
+}
+
+console.log(typeof privateScope);
+// "undefined"
+
+var thing = new Thing();
+
+console.log(thing);
+// Thing {someProperty: "foo"}
+
+thing.showPublic();
+// "foo"
+
+thing.showPrivate();
+// 1
+
+ +

Такий самий шаблон приватності з використанням замикань для локальних змінних можна створити через var, але це потребує функціональної області видимості (зазвичай, це НВФВ у шаблоні модуль) замість просто блочної області видимості у вищенаведеному прикладі.

+ +

Повторні оголошення

+ +

Повторне оголошення тієї самої змінної у області видимості тієї самої функції чи блоку спричиняє помилку {{jsxref("SyntaxError")}}.

+ +
if (x) {
+  let foo;
+  let foo; // викидається SyntaxError.
+}
+
+ +

Ви можете стикнутися з помилками у конструкціях switch, бо вони мають лише один блок.

+ +
let x = 1;
+switch(x) {
+  case 0:
+    let foo;
+    break;
+
+  case 1:
+    let foo; // SyntaxError через повторне оголошення.
+    break;
+}
+ +

Однак, важливо зазначити, що блок, вкладений у блок case, створить нове лексичне середовище блочної області видимості, яке не викличе помилок повторного оголошення, показаних вище.

+ +
let x = 1;
+
+switch(x) {
+  case 0: {
+    let foo;
+    break;
+  }
+  case 1: {
+    let foo;
+    break;
+  }
+}
+ +

Тимчасова мертва зона

+ +

На відміну від змінних, оголошених через var, які спочатку мають значення undefined, let-змінні не ініціалізуються, поки не відбудеться обчислення їхнього оголошення. Звернення до змінної до ініціалізації призводить до викидання ReferenceError. Змінна знаходиться у "тимчасовій мертвій зоні" від початку блоку і до проходження ініціалізації.

+ +
function do_something() {
+  console.log(bar); // undefined
+  console.log(foo); // ReferenceError
+  var bar = 1;
+  let foo = 2;
+}
+ +

Тимчасова мертва зона та typeof

+ +

На відміну від просто неоголошених змінних та змінних, що містять значення undefined, використання оператора typeof для перевірки типу змінної, що знаходиться у своїй ТМЗ, викине ReferenceError:

+ +
// виведе 'undefined'
+console.log(typeof undeclaredVariable);
+// призведе до 'ReferenceError'
+console.log(typeof i);
+let i = 10;
+ +

Ще один приклад тимчасової мертвої зони у поєднанні з лексичною областю видимості

+ +

Через наявність лексичної області видимості, ідентифікатор foo у виразі (foo + 55) оцінюється як ідентифікатор foo блоку if, а не розташована вище змінна foo зі значенням 33.

+ +

У цьому конретному рядку змінна foo блоку if вже була створена у лексичному середовищі, але ще не пройшла (і перервала) свою ініціалізацію (яка є частиною інструкції).

+ +

Змінна foo блоку if досі у тимчасовій мертвій зоні.

+ +
function test(){
+   var foo = 33;
+   if (true) {
+      let foo = (foo + 55); // ReferenceError
+   }
+}
+test();
+ +

Цей феномен може заплутати, наприклад, у наступній ситуації. Інструкція let n of n.a вже знаходиться всередині приватної області видимості блоку циклу for. Отже, ідентифікатор n.a вважається властивістю 'a' об'єкта 'n', розташованого у першій частині цієї ж інструкції ("let n").

+ +

Він досі знаходиться у тимчасовій мертвій зоні, оскільки його оголошення ще не було виконано та перервалось.

+ +
function go(n) {
+  // n тут визначений!
+  console.log(n); // Object {a: [1,2,3]}
+
+  for (let n of n.a) { // ReferenceError
+    console.log(n);
+  }
+}
+
+go({a: [1, 2, 3]});
+
+ +

Інші ситуації

+ +

При використанні всередині блоку, let обмежує область видимості змінної цим блоком. Зауважте відмінність від var, чия область видимості - функція, де відбулось оголошення.

+ +
var a = 1;
+var b = 2;
+
+if (a === 1) {
+  var a = 11; // глобальна область видимості
+  let b = 22; // областю видимості є блок if
+
+  console.log(a);  // 11
+  console.log(b);  // 22
+}
+
+console.log(a); // 11
+console.log(b); // 2
+
+ +

Однак, комбінація оголошень var та let, наведена нижче, спричинить SyntaxError через підняття var наверх блоку. Це призводить до неявного повторного оголошення змінної.

+ +
let x = 1;
+
+{
+  var x = 2; // SyntaxError через повторне оголошення
+}
+
+ +

Специфікації

+ + + + + + + + + + + + + + + + + + + +
СпецифікаціяСтатусКоментар
{{SpecName('ES2015', '#sec-let-and-const-declarations', 'Let and Const Declarations')}}{{Spec2('ES2015')}}Початкове визначення. Не визначає let-вирази та let-блоки.
{{SpecName('ESDraft', '#sec-let-and-const-declarations', 'Let and Const Declarations')}}{{Spec2('ESDraft')}}
+ +

Сумісність з веб-переглядачами

+ + + +

{{Compat("javascript.statements.let")}}

+ +

Див. також

+ + -- cgit v1.2.3-54-g00ecf