diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
commit | 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 (patch) | |
tree | a9ef8ac1e1b8fe4207b6d64d3841bfb8990b6fd0 /files/uk/web/javascript/reference/statements/let/index.html | |
parent | 074785cea106179cb3305637055ab0a009ca74f2 (diff) | |
download | translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.gz translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.bz2 translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.zip |
initial commit
Diffstat (limited to 'files/uk/web/javascript/reference/statements/let/index.html')
-rw-r--r-- | files/uk/web/javascript/reference/statements/let/index.html | 272 |
1 files changed, 272 insertions, 0 deletions
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 +--- +<div>{{jsSidebar("Statements")}}</div> + +<p>Оператор <strong><code>let</code></strong> оголошує локальну змінну блочної області видимості, з необов'язковим присвоєнням їй початкового значення.</p> + +<div>{{EmbedInteractiveExample("pages/js/statement-let.html")}}</div> + + + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox">let <em>var1</em> [= <em>value1</em>] [, <em>var2</em> [= <em>value2</em>]] [, ..., <em>varN</em> [= <em>valueN</em>];</pre> + +<h3 id="Параметри">Параметри</h3> + +<dl> + <dt><code>var1</code>, <code>var2</code>, …, <code>varN</code></dt> + <dd>Імена змінної або змінних, що оголошуються. Кожне ім'я має бути дозволеним ідентифікатором JavaScript.</dd> + <dt><code>value1</code>, <code>value2</code>, …, <code>valueN</code> {{optional_inline}}</dt> + <dd>Для кожної оголошеної змінної ви можете вказати її початкове значення будь-яким дозволеним виразом JavaScript.</dd> +</dl> + +<h2 id="Опис">Опис</h2> + +<p>Оператор <strong><code>let</code></strong> дозволяє оголошувати змінні, що обмежені областю видимості {{jsxref("statements/block", "блоку")}} або виразу, для якого використовуються, на відміну від ключового слова {{jsxref("statements/var", "var")}}, яке визначає змінну глобально, чи локально для всієї функції, незалежно від області видимості блоку. Інша відмінність між операторами {{jsxref("statements/var", "var")}} та <code>let</code> полягає в тому, що останній ініціалізується тільки після <a href="#Тимчасова_мертва_зона">оцінювання синтаксичним аналізатором (дивіться нижче)</a>.</p> + +<p>Як і {{jsxref("statements/const", "const", "Description")}}, <code>let</code> <em>не</em> створює властивостей об'єкта {{domxref('window')}} при глобальному оголошенні (у області видимості верхнього рівня).</p> + +<p>Пояснення, чому була обрана назва "<strong>let</strong>" можна подивитись <a href="https://stackoverflow.com/questions/37916940/why-was-the-name-let-chosen-for-block-scoped-variable-declarations-in-javascri">тут</a>.</p> + +<h3 id="Правила_області_видимості">Правила області видимості</h3> + +<p>Областю видимості змінних, оголошених через <strong><code>let</code></strong>, є блок, у якому вони визначені, а також будь-які вкладені в нього блоки. У цьому сенсі <strong><code>let</code></strong> дуже схожий на <strong><code>var</code></strong>. Головна відмінність полягає в тому, що областю видимості змінної <strong><code>var</code></strong> є уся замикаюча функція:</p> + +<pre class="brush:js">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 +} +</pre> + +<p id="Scoping_rules">На верхньому рівні програм та функцій <strong><code>let</code></strong>, на відміну від <strong><code>var</code></strong>, не створює властивості глобального об'єкта. Наприклад:</p> + +<pre class="brush:js">var x = 'глобальна'; +let y = 'глобальна'; +console.log(this.x); // "глобальна" +console.log(this.y); // undefined +</pre> + +<h3 id="Імітація_приватних_членів">Імітація приватних членів</h3> + +<p>Працюючи з <a href="/uk/docs/Glossary/Constructor">конструкторами</a>, можна використовувати <strong><code>let</code></strong>-зв'язування для створення приватних членів без використання <a href="/uk/docs/Web/JavaScript/Closures">замикань</a>:</p> + +<pre class="brush:js">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 +</pre> + +<p>Такий самий шаблон приватності з використанням замикань для локальних змінних можна створити через <code>var</code>, але це потребує функціональної області видимості (зазвичай, це НВФВ у шаблоні модуль) замість просто блочної області видимості у вищенаведеному прикладі.</p> + +<h3 id="Повторні_оголошення">Повторні оголошення</h3> + +<p>Повторне оголошення тієї самої змінної у області видимості тієї самої функції чи блоку спричиняє помилку {{jsxref("SyntaxError")}}.</p> + +<pre class="brush: js example-bad">if (x) { + let foo; + let foo; // викидається SyntaxError. +} +</pre> + +<p>Ви можете стикнутися з помилками у конструкціях <a href="/uk/docs/JavaScript/Reference/Statements/switch"><code>switch</code></a>, бо вони мають лише один блок.</p> + +<pre class="brush: js example-bad">let x = 1; +switch(x) { + case 0: + let foo; + break; + + case 1: + let foo; // SyntaxError через повторне оголошення. + break; +}</pre> + +<p>Однак, важливо зазначити, що блок, вкладений у блок case, створить нове лексичне середовище блочної області видимості, яке не викличе помилок повторного оголошення, показаних вище.</p> + +<pre class="brush: js">let x = 1; + +switch(x) { + case 0: { + let foo; + break; + } + case 1: { + let foo; + break; + } +}</pre> + +<h3 id="Тимчасова_мертва_зона">Тимчасова мертва зона</h3> + +<p>На відміну від змінних, оголошених через <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting">var</a></code>, які спочатку мають значення <code>undefined</code>, <code>let</code>-змінні <em>не</em> ініціалізуються, поки не відбудеться обчислення їхнього оголошення. Звернення до змінної до ініціалізації призводить до викидання <code><a href="/uk/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError">ReferenceError</a></code>. Змінна знаходиться у "тимчасовій мертвій зоні" від початку блоку і до проходження ініціалізації.</p> + +<pre class="brush: js example-bad">function do_something() { + console.log(bar); // undefined + console.log(foo); // ReferenceError + var bar = 1; + let foo = 2; +}</pre> + +<h3 id="Тимчасова_мертва_зона_та_typeof">Тимчасова мертва зона та <code>typeof</code></h3> + +<p>На відміну від просто неоголошених змінних та змінних, що містять значення <code>undefined</code>, використання оператора <code>typeof</code> для перевірки типу змінної, що знаходиться у своїй ТМЗ, викине <code>ReferenceError</code>:</p> + +<pre class="brush: js">// виведе 'undefined' +console.log(typeof undeclaredVariable); +// призведе до 'ReferenceError' +console.log(typeof i); +let i = 10;</pre> + +<h3 id="Ще_один_приклад_тимчасової_мертвої_зони_у_поєднанні_з_лексичною_областю_видимості">Ще один приклад тимчасової мертвої зони у поєднанні з лексичною областю видимості</h3> + +<p>Через наявність лексичної області видимості, ідентифікатор <code>foo</code> у виразі <code>(foo + 55)</code> оцінюється як ідентифікатор foo блоку if, а не розташована вище змінна foo зі значенням 33.</p> + +<p>У цьому конретному рядку змінна <code>foo</code> блоку if вже була створена у лексичному середовищі, але ще не пройшла (і перервала) свою ініціалізацію (яка є частиною інструкції).</p> + +<p>Змінна <code>foo</code> блоку if досі у тимчасовій мертвій зоні.</p> + +<pre class="brush: js example-bad">function test(){ + var foo = 33; + if (true) { + let foo = (foo + 55); // ReferenceError + } +} +test();</pre> + +<p>Цей феномен може заплутати, наприклад, у наступній ситуації. Інструкція <code>let n of n.a</code> вже знаходиться всередині приватної області видимості блоку циклу for. Отже, ідентифікатор <code>n.a</code> вважається властивістю 'a' об'єкта 'n', розташованого у першій частині цієї ж інструкції ("let n").</p> + +<p>Він досі знаходиться у тимчасовій мертвій зоні, оскільки його оголошення ще не було виконано та перервалось.</p> + +<pre class="brush: js example-bad">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]}); +</pre> + +<h2 id="Інші_ситуації">Інші ситуації</h2> + +<p>При використанні всередині блоку, <strong><code>let</code></strong> обмежує область видимості змінної цим блоком. Зауважте відмінність від <code><strong>var</strong></code><em>,</em> чия область видимості - функція, де відбулось оголошення.</p> + +<pre class="brush: js">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 +</pre> + +<p>Однак, комбінація оголошень <code><strong>var</strong></code> та <strong><code>let</code></strong>, наведена нижче, спричинить <code>SyntaxError </code>через підняття <code><strong>var</strong></code> наверх блоку. Це призводить до неявного повторного оголошення змінної.</p> + +<pre class="brush: js example-bad">let x = 1; + +{ + var x = 2; // SyntaxError через повторне оголошення +} +</pre> + +<h2 id="Специфікації">Специфікації</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Специфікація</th> + <th scope="col">Статус</th> + <th scope="col">Коментар</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-let-and-const-declarations', 'Let and Const Declarations')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Початкове визначення. Не визначає let-вирази та let-блоки.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-let-and-const-declarations', 'Let and Const Declarations')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Сумісність_з_веб-переглядачами">Сумісність з веб-переглядачами</h2> + + + +<p>{{Compat("javascript.statements.let")}}</p> + +<h2 id="Див._також">Див. також</h2> + +<ul> + <li><a href="/uk/docs/Web/JavaScript/Reference/Statements/var"><code>var</code></a></li> + <li><a href="/uk/docs/Web/JavaScript/Reference/Statements/const"><code>const</code></a></li> + <li><a href="https://hacks.mozilla.org/2015/07/es6-in-depth-let-and-const/">ES6 In Depth: <code>let</code> and <code>const</code></a></li> + <li><a href="https://blog.mozilla.org/addons/2015/10/14/breaking-changes-let-const-firefox-nightly-44/">Breaking changes in <code>let</code> and <code>const</code> in Firefox 44</a></li> + <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch3.md">You Don't Know JS: Scope & Closures: Chapter 3: Function vs. Block Scope</a></li> + <li><a href="https://stackoverflow.com/a/33198850/1125029">StackOverflow: What is the Temporal Dead Zone. </a></li> + <li><a href="https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var-to-declare-a-variable">StackOverflow: What is the difference between using let and var?</a></li> +</ul> |