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/for...of/index.html | |
| 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/for...of/index.html')
| -rw-r--r-- | files/ru/web/javascript/reference/statements/for...of/index.html | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/statements/for...of/index.html b/files/ru/web/javascript/reference/statements/for...of/index.html new file mode 100644 index 0000000000..0074719d06 --- /dev/null +++ b/files/ru/web/javascript/reference/statements/for...of/index.html @@ -0,0 +1,302 @@ +--- +title: for...of +slug: Web/JavaScript/Reference/Statements/for...of +tags: + - ECMAScript6 + - JavaScript + - Оператор + - Экспериментальный +translation_of: Web/JavaScript/Reference/Statements/for...of +--- +<div>{{jsSidebar("Statements")}}</div> + +<h2 id="Summary" name="Summary">Сводка</h2> + +<p>Оператор <code>for...of</code> выполняет цикл обхода <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/iterable">итерируемых объектов</a> (включая {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, объект <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments">аргументов</a> и подобных), вызывая на каждом шаге итерации операторы для каждого значения из различных свойств объекта.</p> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox notranslate">for (<em>variable</em> of <em>iterable</em>) { + <em>statement</em> +} +</pre> + +<dl> + <dt><code>variable</code></dt> + <dd>На каждом шаге итерации <code><em>variable</em></code> присваивается значение нового свойства объекта <em><code>iterable</code></em>. Переменная <em><code>variable</code></em> может быть также объявлена с помощью <code>const</code>, <code>let</code> или <code>var</code>.</dd> + <dt><code>iterable</code></dt> + <dd>Объект, перечисляемые свойства которого обходятся во время выполнения цикла.</dd> +</dl> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Обход_jsxrefArray">Обход {{jsxref("Array")}}</h3> + +<pre class="notranslate"><code>let iterable = [10, 20, 30]; + +for (let value of iterable) { + value += 1; + console.log(value); +} +// 11 +// 21 +// 31</code></pre> + +<p>Можно также использовать <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const"><code>const</code></a> вместо <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let"><code>let</code></a>, если не нужно переназначать переменные внутри блока.</p> + +<pre class="notranslate"><code>let iterable = [10, 20, 30]; + +for (const value of iterable) { + console.log(value); +} +// 10 +// 20 +// 30</code></pre> + +<h3 id="Обход_jsxrefString">Обход {{jsxref("String")}}</h3> + +<pre class="notranslate"><code>let iterable = 'boo'; + +for (let value of iterable) { + console.log(value); +} +// "b" +// "o" +// "o"</code></pre> + +<h3 id="Обход_jsxrefTypedArray">Обход {{jsxref("TypedArray")}}</h3> + +<pre class="notranslate"><code>let iterable = new Uint8Array([0x00, 0xff]); + +for (let value of iterable) { + console.log(value); +} +// 0 +// 255</code></pre> + +<h3 id="Обход_jsxrefMap">Обход {{jsxref("Map")}}</h3> + +<pre class="notranslate"><code>let iterable = new Map([['a', 1], ['b', 2], ['c', 3]]); + +for (let entry of iterable) { + console.log(entry); +} +// ['a', 1] +// ['b', 2] +// ['c', 3] + +for (let [key, value] of iterable) { + console.log(value); +} +// 1 +// 2 +// 3</code></pre> + +<h3 id="Обход_jsxrefSet">Обход {{jsxref("Set")}}</h3> + +<pre class="notranslate"><code>let iterable = new Set([1, 1, 2, 2, 3, 3]); + +for (let value of iterable) { + console.log(value); +} +// 1 +// 2 +// 3</code></pre> + +<h3 id="Обход_объекта_jsxrefarguments">Обход объекта {{jsxref("arguments")}} </h3> + +<pre class="notranslate"><code>(function() { + for (let argument of arguments) { + console.log(argument); + } +})(1, 2, 3); + +// 1 +// 2 +// 3</code></pre> + +<h3 id="Обход_DOM_коллекций">Обход DOM коллекций</h3> + +<p>Обход DOM коллекций наподобие {{domxref("NodeList")}}: следующий пример добавляет класс <code>read</code> параграфам, являющимся непосредственными потомками статей:</p> + +<pre class="notranslate"><code>// Примечание: работает только на платформах, где +// реализован NodeList.prototype[Symbol.iterator] +let articleParagraphs = document.querySelectorAll('article > p'); + +for (let paragraph of articleParagraphs) { + paragraph.classList.add('read'); +}</code></pre> + +<h3 id="Закрытие_итераторов">Закрытие итераторов</h3> + +<p>В циклах <code>for...of</code> аварийный выход осуществляется через <code>break</code>, <code>throw</code> или <code>return</code>. Во всех вариантах итератор завершается.</p> + +<pre class="notranslate"><code>function* foo(){ + yield 1; + yield 2; + yield 3; +}; + +for (let o of foo()) { + console.log(o); + break; // итератор закрывается, возврат +}</code> +</pre> + +<h3 id="Обход_генераторов">Обход генераторов</h3> + +<p>Вы можете выполнять обход <a href="/en-US/docs/Web/JavaScript/Reference/Statements/function*">генераторов</a>, вот пример:</p> + +<pre class="brush:js notranslate">function* fibonacci() { // функция-генератор + let [prev, curr] = [0, 1]; + for (;;) { + [prev, curr] = [curr, prev + curr]; + yield curr; + } +} + +for (let n of fibonacci()) { + // ограничивает последовательность на 1000 + if (n > 1000) + break; + console.log(n); +} +</pre> + +<h4 id="Не_пытайтесь_повторно_использовать_генератор">Не пытайтесь повторно использовать генератор</h4> + +<p>Генераторы нельзя использовать дважды, даже если цикл <code>for...of </code> завершится аварийно, например, через оператор {{jsxref("Statements/break", "break")}} . При выходе из цикла генератор завершается, и любые попытки получить из него значение обречены.</p> + +<pre class="brush: js example-bad notranslate"><code>var gen = (function *(){ + yield 1; + yield 2; + yield 3; +})(); +for (let o of gen) { + console.log(o); + break; // Завешение обхода +} + +// Генератор нельзя повторно обойти, следующее не имеет смысла! +for (let o of gen) { + console.log(o); // Не будет вызван +}</code></pre> + +<h3 id="Обход_итерируемых_объектов">Обход итерируемых объектов</h3> + +<p>Кроме того, можно сделать обход объекта, явно реализующего <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#iterable">iterable</a>:</p> + +<pre class="notranslate"><code>var iterable = { + [Symbol.iterator]() { + return { + i: 0, + next() { + if (this.i < 3) { + return { value: this.i++, done: false }; + } + return { value: undefined, done: true }; + } + }; + } +}; + +for (var value of iterable) { + console.log(value); +} +// 0 +// 1 +// 2</code></pre> + +<h3 id="Различия_между_for...of_и_for...in">Различия между <code>for...of</code> и <code>for...in</code></h3> + +<p>Оба оператора, и <code>for...in</code> и <code>for...of</code> производят обход объектов . Разница в том, как они это делают.</p> + +<p>Для {{jsxref("Statements/for...in", "for...in")}} обход <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Enumerability_and_ownership_of_properties" title="перечисляемые свойства">перечисляемых свойств</a> объекта осуществляется в произвольном порядке.</p> + +<p>Для <code>for...of</code> обход происходит в соответствии с тем, какой порядок определен в <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/iterable">итерируемом объекте</a>.</p> + +<p>Следующий пример показывает различия в работе циклов <code>for...of</code> и <code>for...in</code> при обходе {{jsxref("Array")}}.</p> + +<pre class="notranslate"><code>Object.prototype.objCustom = function() {}; +Array.prototype.arrCustom = function() {}; + +let iterable = [3, 5, 7]; +iterable.foo = 'hello'; + +for (let i in iterable) { + console.log(i); // выведет 0, 1, 2, "foo", "arrCustom", "objCustom" +} + +for (let i in iterable) { + if (iterable.hasOwnProperty(i)) { + console.log(i); // выведет 0, 1, 2, "foo" + } +} + +for (let i of iterable) { + console.log(i); // выведет 3, 5, 7 +}</code></pre> + +<p>Разберемся шаг за шагом в вышеописанном коде.</p> + +<pre class="notranslate"><code>Object.prototype.objCustom = function() {}; +Array.prototype.arrCustom = function() {}; + +let iterable = [3, 5, 7]; +iterable.foo = 'hello';</code></pre> + +<p>Каждый объект унаследует метод <code>objCustom</code> и каждый массив {{jsxref("Array")}} унаследует метод <code>arrCustom</code> благодаря созданию их в {{jsxref("Object.prototype")}} и {{jsxref("Array.prototype")}}. Объект <code>iterable</code> унаследует методы <code>objCustom</code> и <code>arrCustom</code> из-за <a href="/ru/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">наследования через прототип</a>.</p> + +<pre class="notranslate"><code>for (let i in iterable) { + console.log(i); // выведет 0, 1, 2, "foo", "arrCustom", "objCustom" +}</code></pre> + +<p>Цикл выводит только <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">перечисляемые свойства</a> объекта <code>iterable</code>, в порядке их создания. Он не выводит <strong>значения</strong> <code>3</code>, <code>5</code>, <code>7</code> и <code>hello</code> поскольку они <strong>не являются</strong> перечисляемыми, фактически они вообще не являются свойствами, они являютя <strong>значениями</strong>. Выводятся же <strong>имена свойств и методов</strong>, например <code>arrCustom</code> и <code>objCustom</code>. Если вы еще не совсем поняли, по каким свойствам осуществляется обход, вот дополнительное объяснение того, как работает {{jsxref("Statements/for...in", "array iteration and for...in", "#Array_iteration_and_for...in")}} .</p> + +<pre class="notranslate"><code>for (let i in iterable) { + if (iterable.hasOwnProperty(i)) { + console.log(i); // выведет 0, 1, 2, "foo" + } +}</code></pre> + +<p>Цикл аналогичен предыдущему, но использует {{jsxref("Object.prototype.hasOwnProperty()", "hasOwnProperty()")}} для проверки того, собственное ли это свойство объекта или унаследованое. Выводятся только собственные свойства. Имена <code>0</code>, <code>1</code>, <code>2</code> и <code>foo</code> принадлежат только экземпляру объекта (<strong>не унаследованы</strong>). Методы <code>arrCustom</code> и <code>objCustom</code> не выводятся, поскольку они <strong>унаследованы</strong>.</p> + +<pre class="notranslate"><code>for (let i of iterable) { + console.log(i); // выведет 3, 5, 7 +}</code></pre> + +<p>Этот цикл обходит <code>iterable</code> и выводит те значения <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Iterators_and_Generators$edit#%D0%98%D1%82%D0%B5%D1%80%D0%B8%D1%80%D1%83%D0%B5%D0%BC%D1%8B%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B">итерируемого объекта</a>,<strong> </strong>которые определены в способе его перебора, т.е. не свойства объекта, а значения массива <code>3</code>, <code>5</code>, <code>7</code> .</p> + +<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-for-in-and-for-of-statements', 'for...of statement')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Изначальное опеределение.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'for...of statement')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p>{{Compat("javascript.statements.for_of")}}</p> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li>{{jsxref("Array.prototype.forEach()")}}</li> + <li>{{jsxref("Map.prototype.forEach()")}}</li> + <li>{{jsxref("Object.entries()")}}</li> +</ul> |
