diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/javascript/reference/statements/let | |
parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
download | translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2 translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip |
initial commit
Diffstat (limited to 'files/ru/web/javascript/reference/statements/let')
-rw-r--r-- | files/ru/web/javascript/reference/statements/let/index.html | 414 |
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 <= 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 <= 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 < 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<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><script type="application/javascript;version=1.7"></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> |