aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/statements/let
diff options
context:
space:
mode:
Diffstat (limited to 'files/ru/web/javascript/reference/statements/let')
-rw-r--r--files/ru/web/javascript/reference/statements/let/index.html414
1 files changed, 414 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/statements/let/index.html b/files/ru/web/javascript/reference/statements/let/index.html
new file mode 100644
index 0000000000..ac3e59d716
--- /dev/null
+++ b/files/ru/web/javascript/reference/statements/let/index.html
@@ -0,0 +1,414 @@
+---
+title: let
+slug: Web/JavaScript/Reference/Statements/let
+translation_of: Web/JavaScript/Reference/Statements/let
+---
+<div>{{jsSidebar("Statements")}}</div>
+
+<div>Директива <code><strong>let</strong></code> объявляет переменную с блочной областью видимости с возможностью инициализировать её значением.</div>
+
+<div></div>
+
+<h2 id="Синтаксис">Синтаксис</h2>
+
+<pre class="syntaxbox">let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];
+</pre>
+
+<h3 id="Параметры">Параметры</h3>
+
+<dl>
+ <dt><code>var1</code>, <code>var2</code>, …, <code>varN</code></dt>
+ <dd>Имя переменной. Может использоваться любой допустимый идентификатор.</dd>
+ <dt><code>value1</code>, <code>value2</code>, …, <code>valueN</code></dt>
+ <dd>Значение переменной. Любое допустимое выражение.</dd>
+</dl>
+
+<h2 id="Описание">Описание</h2>
+
+<p>Директива <code><strong>let</strong></code><strong> </strong>позволяет объявить локальную переменную с областью видимости, ограниченной текущим блоком кода . В отличие от ключевого слова <a href="/en-US/docs/JavaScript/Reference/Statements/var" title="JavaScript/Reference/Statements/var"><code>var</code></a>, которое объявляет переменную глобально или локально во всей функции, независимо от области блока.</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="Правила_области_видимости_2">Правила области видимости</h3>
+
+<p>Областью видимости переменных, объявленных ключевым словом <code>let</code>, является блок, в котором они объявлены, и все его подблоки. В этом работа директива <code>let</code> схожа с работой директивы <code>var</code>. Основная разница заключается в том, что областью видимости переменной, объявленной директивой <code>var</code>, является вся функция, в которой она объявлена:</p>
+
+<pre class="brush:js">function varTest() {
+ var x = 1;
+ if (true) {
+ var x = 2; // та же переменная!
+ console.log(x); // 2
+ }
+ console.log(x); // 2
+}
+
+function letTest() {
+ let x = 1;
+ if (true) {
+ let x = 2; // другая переменная
+ console.log(x); // 2
+ }
+ console.log(x); // 1
+}
+</pre>
+
+<h3 id="sect1"></h3>
+
+<h3 id="Чище_код_во_вложенных_функциях">Чище код во вложенных функциях</h3>
+
+<p><code>let</code> иногда делает код чище при использовании вложенных функций.</p>
+
+<pre class="brush: js">var list = document.getElementById("list");
+
+for (let i = 1; i &lt;= 5; i++) {
+ let item = document.createElement('li');
+ item.appendChild(document.createTextNode('Item ' + i));
+
+ item.onclick = function(ev) {
+ console.log('Item ' + i + ' is clicked.');
+ };
+ list.appendChild(item);
+}
+
+// чтобы получить такой же эффект с использованием 'var'
+// необходимо создать новый контекст
+// используя замыкание, чтобы сохранить значение неизменённым
+for (var i = 1; i &lt;= 5; i++) {
+ var item = document.createElement("li");
+ item.appendChild(document.createTextNode("Item " + i));
+
+ (function(i){
+ item.onclick = function(ev) {
+ console.log('Item ' + i + ' is clicked.');
+ };
+ })(i);
+ list.appendChild(item);
+}</pre>
+
+<p>Пример выше будет выполнен как и ожидается, так как пять экземпляров внутренней функции (анонимной) будут ссылаться на пять разных экземпляров переменной <code>i</code>. Пример будет выполнен неверно, если заменить директиву <code>let</code> на <code>var,</code> или удалить переменную <code>i</code> из параметров вложенной функции и использовать внешнюю переменную <code>i</code> во внутренней функции.</p>
+
+<p id="Правила_области_видимости">На верхнем уровне скриптов и функций <code>let, в отличии от var, не создает свойства на глобальном объекте</code>. Например:</p>
+
+<pre class="brush:js">var x = 'global_x';
+let y = 'global_y';
+console.log(this.x); // 'global_x'
+console.log(this.y); // undefined
+</pre>
+
+<p>В выводе программы будет отображено слово "global_x" для <code>this.x</code>, но <code>undefined</code> для <code>this.y</code>.</p>
+
+<h3 id="Эмуляция_приватных_членов">Эмуляция приватных членов</h3>
+
+<p>При взаимодействии с <a href="https://developer.mozilla.org/en-US/docs/Glossary/Constructor">конструкторами</a> можно использовать выражение <strong><code>let</code></strong> чтобы открыть доступ к одному или нескольким приватным членам через использование <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures">замыканий</a>:</p>
+
+<pre class="brush: js">var SomeConstructor;
+
+{
+ let privateScope = {};
+
+ SomeConstructor = function SomeConstructor() {
+ this.someProperty = 'foo';
+ privateScope.hiddenProperty = 'bar';
+ }
+
+ SomeConstructor.prototype.showPublic = function() {
+ console.log(this.someProperty); // foo
+ }
+
+ SomeConstructor.prototype.showPrivate = function() {
+ console.log(privateScope.hiddenProperty); // bar
+ }
+
+}
+
+var myInstance = new SomeConstructor();
+
+myInstance.showPublic();
+myInstance.showPrivate();
+
+console.log(privateScope.hiddenProperty); // error</pre>
+
+<p>Эта техника позволяет получить только "статичное" приватное состояние - в примере выше, все экземпляры полученные из конструктора <code>SomeConstructor</code> будут ссылаться на одну и ту же область видимости <code>privateScope</code>.</p>
+
+<h3 id="Временные_мертвые_зоны_и_ошибки_при_использовании_let">Временные мертвые зоны и ошибки при использовании <code>let</code></h3>
+
+<p>Повторное объявление той же переменной в том же блоке или функции приведет к выбросу исключения <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError">SyntaxError</a>.</p>
+
+<pre class="brush: js">if (x) {
+ let foo;
+ let foo; // SyntaxError thrown.
+}</pre>
+
+<p>В стандарте ECMAScript 2015 переменные, объявленные директивой let, переносятся в начало блока. Но если вы сошлетесь в блоке на переменную, до того как она объявлена директивой let, то это приведет к выбросу исключения <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/ReferenceError" title="TypeError">ReferenceError</a></code>, потому что переменная находится во "временной мертвой зоне" с начала блока и до места ее объявления. (В отличии от переменной, объявленной через <code>var</code>, которая просто будет содержать значение <code>undefined</code>)</p>
+
+<pre class="brush: js"><code>function do_something() {
+ console.log(bar); // undefined
+ console.log(foo); // ReferenceError: foo is not defined
+ var bar = 1;
+ let foo = 2;
+}</code></pre>
+
+<p>Вы можете столкнуться с ошибкой в операторах блока  <code><a href="/en-US/docs/JavaScript/Reference/Statements/switch" title="switch">switch</a></code>, так как он имеет только один подблок.</p>
+
+<pre class="brush: js">switch (x) {
+  case 0:
+    let foo;
+    break;
+
+  case 1:
+    let foo; // Выброс SyntaxError из-за повторного объявления переменной
+    break;
+}</pre>
+
+<h3 id="Использование_let_в_циклах_for"><code>Использование let в циклах</code> <code>for</code></h3>
+
+<p>Вы можете использовать ключевое слово <code>let</code> для привязки переменных к локальной области видимости цикла <code>for</code>. Разница с использованием <code>var</code> в заголовке цикла <code>for</code>, заключается в том, что переменные объявленные <code>var</code>, будут видны во всей функции, в которой находится этот цикл.</p>
+
+<pre class="brush:js">var i=0;
+for ( let i=i ; i &lt; 10 ; i++ ) {
+ console.log(i);
+}
+</pre>
+
+<h3 id="Правила_области_видимости_3">Правила области видимости</h3>
+
+<pre class="brush: js">for (let <var>expr1</var>; <var>expr2</var>; <var>expr3</var>) <var>statement</var>
+</pre>
+
+<p>В этом примере <var>expr2</var>, <var>expr3, statement </var> заключены в неявный блок, который содержит блок локальных переменных, объявленых конструкцией <code>let <em>expr1</em></code>. Пример приведен выше.</p>
+
+<h2 id="Примеры">Примеры</h2>
+
+<h3 id="let_vs_var"><code>let</code> vs <code>var</code></h3>
+
+<p>Когда let используется внутри блока, то область видимости переменной ограничивается этим блоком. Напомним, что отличие заключается в том, что областью видимости переменных, объявленных диретивой var, является вся функция, в которой они были объявлены.</p>
+
+<pre class="brush: js">var a = 5;
+var b = 10;
+
+if (a === 5) {
+ let a = 4; // The scope is inside the if-block
+ var b = 1; // The scope is inside the function
+
+ console.log(a); // 4
+ console.log(b); // 1
+}
+
+console.log(a); // 5
+console.log(b); // 1</pre>
+
+<h3 id="let_в_циклах"><code>let</code> в циклах</h3>
+
+<p>Вы можете использовать ключевое слово <code>let</code> для привязки переменных к локальной области видимости цикла <code>for</code>, вместо того что бы использовать глобальные переменные (объявленные с помощью <code>var</code>).</p>
+
+<pre class="brush: js">for (let i = 0; i&lt;10; i++) {
+ console.log(i); // 0, 1, 2, 3, 4 ... 9
+}
+
+console.log(i); // i is not defined</pre>
+
+<h2 id="Нестандартизированные_расширения_let">Нестандартизированные расширения <code>let</code></h2>
+
+<h3 id="let_блок"><code>let</code> блок</h3>
+
+<div class="warning">
+<p><code>Поддержка let</code> блоков была убрана в Gecko 44  {{bug(1023609)}}.</p>
+</div>
+
+<p><strong>let блок</strong> предоставляет способ, ассоциировать значения с перемеными внутри области видимости этого блока, без влияния на значения переменных с теми же именами вне этого блока.</p>
+
+<h4 id="Синтаксис_2">Синтаксис</h4>
+
+<pre class="brush: js">let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) block;
+</pre>
+
+<h4 id="Описание_2">Описание</h4>
+
+<p><strong><code>let</code> </strong>блок предоставляет локальную область видимости для переменных. Работа его заключается в привязке нуля или более переменных к области видимости этого блока кода, другими словами, он является блоком операторов. Отметим, что область видимости переменных, объявленных директивой <code>var</code>, в <strong>блоке <code>let</code></strong>, будет той же самой, что и если бы эти переменные были объявленны вне <strong>блока <code>let</code></strong>, иными словами областью видимости таких переменных по-прежнему является функция. Скобки в<strong> блоке </strong><code><strong>let</strong></code> являются обязательными. Опускание их приведет к синтаксической ошибке.</p>
+
+<h4 id="Пример">Пример</h4>
+
+<pre class="brush:js">var x = 5;
+var y = 0;
+
+let (x = x+10, y = 12) {
+ console.log(x+y); // 27
+}
+
+console.log(x + y); // 5
+</pre>
+
+<p>Правила для этого блока кода аналогичны как и для любого другого блока кода в JavaScript. Он может содержать свои локальные переменные, объявленные <code>let</code>.</p>
+
+<h4 id="Правила_области_видимости_4">Правила области видимости</h4>
+
+<p>Областью видимости переменных, объявленных директивой <code>let</code>, в <strong>блоке </strong><code><strong>let</strong></code> является сам блок и все подблоки в нем, если они не содержат объявлений переменных с теми же именами. </p>
+
+<h3 id="let_выражения"><code>let</code> выражения</h3>
+
+<div class="warning">
+<p><code>Поддержка let выражений</code> была убрана в Gecko 41  {{bug(1023609)}}.</p>
+</div>
+
+<p><strong><code>let выражение</code></strong> позволяет объявить переменные с областью видимости ограниченной одним выражением.</p>
+
+<h4 id="Синтаксис_3">Синтаксис</h4>
+
+<pre class="syntaxbox">let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) expression;</pre>
+
+<h4 id="Пример_2">Пример</h4>
+
+<p>Вы можете использовать let для объявления переменных, областью видимости которых является только одно выражение:</p>
+
+<pre class="brush: js">var a = 5;
+let(a = 6) console.log(a); // 6
+console.log(a); // 5</pre>
+
+<h4 id="Правила_области_видимости_5">Правила области видимости</h4>
+
+<p>В данном <strong><code>let</code> выражении</strong>:</p>
+
+<pre class="brush: js">let (<var>decls</var>) <var>expr</var>
+</pre>
+
+<p><em><code>expr</code> </em>оборачивается в неявный блок.</p>
+
+<h2 id="Спецификации">Спецификации</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Specification</th>
+ <th scope="col">Status</th>
+ <th scope="col">Comment</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>{{CompatibilityTable}}</p>
+
+<div id="compat-desktop">
+<table class="compat-table">
+ <tbody>
+ <tr>
+ <th>Feature</th>
+ <th>Chrome</th>
+ <th>Firefox (Gecko)</th>
+ <th>Internet Explorer</th>
+ <th>Opera</th>
+ <th>Safari</th>
+ </tr>
+ <tr>
+ <td>Basic support</td>
+ <td>
+ <p class="p1">{{CompatChrome(41.0)}}</p>
+ </td>
+ <td>{{ CompatGeckoDesktop("1.8.1") }} [1]</td>
+ <td>11</td>
+ <td>17</td>
+ <td>{{CompatUnknown}}</td>
+ </tr>
+ <tr>
+ <td>Temporal dead zone</td>
+ <td>{{CompatUnknown}}</td>
+ <td>{{ CompatGeckoDesktop("35") }} [1]</td>
+ <td>{{CompatUnknown}}</td>
+ <td>{{CompatUnknown}}</td>
+ <td>{{CompatUnknown}}</td>
+ </tr>
+ <tr>
+ <td><code>let</code> expression {{non-standard_inline}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{ CompatGeckoDesktop("1.8.1") }} [1]</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatNo}}</td>
+ </tr>
+ <tr>
+ <td><code>let</code> block {{non-standard_inline}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{ CompatGeckoDesktop("1.8.1") }} [1]</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatNo}}</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+<div id="compat-mobile">
+<table class="compat-table">
+ <tbody>
+ <tr>
+ <th>Feature</th>
+ <th>Android</th>
+ <th>Chrome for Android</th>
+ <th>Firefox Mobile (Gecko)</th>
+ <th>IE Mobile</th>
+ <th>Opera Mobile</th>
+ <th>Safari Mobile</th>
+ </tr>
+ <tr>
+ <td>Basic support</td>
+ <td>{{CompatUnknown}}</td>
+ <td>
+ <p class="p1">{{CompatChrome(41.0)}}</p>
+ </td>
+ <td>{{ CompatGeckoMobile("1.8.1") }} [1]</td>
+ <td>{{CompatUnknown}}</td>
+ <td>{{CompatUnknown}}</td>
+ <td>{{CompatUnknown}}</td>
+ </tr>
+ <tr>
+ <td>Temporal dead zone</td>
+ <td>{{CompatUnknown}}</td>
+ <td>{{CompatUnknown}}</td>
+ <td>{{ CompatGeckoMobile("35") }} [1]</td>
+ <td>{{CompatUnknown}}</td>
+ <td>{{CompatUnknown}}</td>
+ <td>{{CompatUnknown}}</td>
+ </tr>
+ <tr>
+ <td><code>let</code> expression {{non-standard_inline}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{ CompatGeckoMobile("1.8.1") }} [1]</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatNo}}</td>
+ </tr>
+ <tr>
+ <td><code>let</code> block {{non-standard_inline}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{ CompatGeckoMobile("1.8.1") }} [1]</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatNo}}</td>
+ <td>{{CompatNo}}</td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+<h3 id="sect2"></h3>
+
+<h3 id="Особенности_Firefox">Особенности Firefox</h3>
+
+<ul>
+ <li>До SpiderMonkey 46 {{geckoRelease(46)}} выбрасывал {{jsxref("TypeError")}} на повторное объявление, вместо {{jsxref("SyntaxError")}} ({{bug(1198833)}}).</li>
+ <li>До SpiderMonkey 44 {{geckoRelease(44)}}, <code>let</code> был доступен только для блоков кода обернутых в HTML <code>&lt;script type="application/javascript;version=1.7"&gt;</code>block (or higher version) и имел другую сематнику.</li>
+ <li>Поддержка в {{domxref("Worker")}} код спрятан за <code>dom.workers.latestJSVersion</code> флагом ({{bug(487070)}}). Без версии <code>let</code>, флаг будет удален в будущем ({{bug(1219523)}}).</li>
+ <li>Соблюдение стандарта ES2015 для <code>let</code> в SpIderMonkey отслеживатся в {{bug(950547)}}</li>
+</ul>