aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/global_objects/array/foreach
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
commit074785cea106179cb3305637055ab0a009ca74f2 (patch)
treee6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/javascript/reference/global_objects/array/foreach
parentda78a9e329e272dedb2400b79a3bdeebff387d47 (diff)
downloadtranslated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz
translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2
translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip
initial commit
Diffstat (limited to 'files/ru/web/javascript/reference/global_objects/array/foreach')
-rw-r--r--files/ru/web/javascript/reference/global_objects/array/foreach/index.html388
1 files changed, 388 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/global_objects/array/foreach/index.html b/files/ru/web/javascript/reference/global_objects/array/foreach/index.html
new file mode 100644
index 0000000000..3787dc7e84
--- /dev/null
+++ b/files/ru/web/javascript/reference/global_objects/array/foreach/index.html
@@ -0,0 +1,388 @@
+---
+title: Array.prototype.forEach()
+slug: Web/JavaScript/Reference/Global_Objects/Array/forEach
+tags:
+ - Array
+ - ECMAScript5
+ - JavaScript
+ - Method
+ - Prototype
+ - Reference
+ - forEach
+ - polyfill
+translation_of: Web/JavaScript/Reference/Global_Objects/Array/forEach
+---
+<div>{{JSRef("Global_Objects", "Array")}}</div>
+
+<p>Метод <code><strong>forEach()</strong></code> выполняет указанную функцию один раз для каждого элемента в массиве.</p>
+
+<div>{{EmbedInteractiveExample("pages/js/array-foreach.html")}}</div>
+
+<p class="hidden">Источник этого интерактивного примера хранится в GitHub. Если вы хотите внести вклад в проект интерактивных примеров, пожалуйста, клонируйте <a href="https://github.com/mdn/interactive-examples"> https://github.com/mdn/interactive-examples</a> и отправьте нам pull request.</p>
+
+<h2 id="Syntax" name="Syntax">Синтаксис</h2>
+
+<pre><var>arr</var>.forEach(function <var>callback(currentValue, index, array) {
+ //your iterator
+}</var>[, <var>thisArg</var>]);</pre>
+
+<h3 id="Parameters" name="Parameters">Параметры</h3>
+
+<dl>
+ <dt><code>callback</code></dt>
+ <dd>Функция, которая будет вызвана для каждого элемента массива. Она принимает от одного до трех аргументов:</dd>
+ <dd>
+ <dl>
+ <dt><code>currentValue</code></dt>
+ <dd>Текущий обрабатываемый элемент в массиве.</dd>
+ <dt><code>index</code>{{optional_inline}}</dt>
+ <dd>Индекс текущего обрабатываемого элемента в массиве.</dd>
+ <dt><code>array</code>{{optional_inline}}</dt>
+ <dd>Массив, по которому осуществляется проход.</dd>
+ </dl>
+ </dd>
+ <dt><code>thisArg</code></dt>
+ <dd>Необязательный параметр. Значение, используемое в качестве <code>this</code> при вызове функции <code>callback</code>.</dd>
+</dl>
+
+<h3 id="Возвращаемое_значение">Возвращаемое значение</h3>
+
+<p>{{jsxref("undefined")}}.</p>
+
+<h2 id="Description" name="Description">Описание</h2>
+
+<p>Метод <code>forEach()</code> выполняет функцию <code>callback</code> один раз для каждого элемента, находящегося в массиве в порядке возрастания. Она не будет вызвана для удалённых или пропущенных элементов массива. Однако, она будет вызвана для элементов, которые присутствуют в массиве и имеют значение {{jsxref("Global_Objects/undefined", "undefined")}}.</p>
+
+<p>Функция <code>callback</code> будет вызвана с <strong>тремя аргументами</strong>:</p>
+
+<ul>
+ <li>значение элемента (<strong>value</strong>)</li>
+ <li>индекс элемента (<strong>index</strong>)</li>
+ <li>массив, по которому осуществляется проход (<strong>array</strong>)</li>
+</ul>
+
+<p>Если в метод <code>forEach()</code> был передан параметр <code>thisArg</code>, при вызове <code>callback</code> он будет использоваться в качестве значения <code>this</code>. В противном случае, в качестве значения <code>this</code> будет использоваться значение {{jsxref("Global_Objects/undefined", "undefined")}}. В конечном итоге, значение <code>this</code>, наблюдаемое из функции <code>callback</code>, определяется согласно {{jsxref('Operators/this', 'обычным правилам определения <code>this</code>, видимого из функции')}}.</p>
+
+<p>Диапазон элементов, обрабатываемых методом <code>forEach()</code>, устанавливается до первого вызова функции <code>callback</code>. Элементы, добавленные в массив после начала выполнения метода <code>forEach()</code>, не будут посещены функцией <code>callback</code>. Если существующие элементы массива изменятся, значения, переданные в функцию <code>callback</code>, будут значениями на тот момент времени, когда метод <code>forEach()</code> посетит их; удалённые элементы посещены не будут. Если уже посещённые элементы удаляются во время итерации (например, с помощью {{jsxref("Array.prototype.shift()", "shift()")}}), последующие элементы будут пропущены. ({{jsxref('Global_Objects/Array/forEach', 'Смотри пример ниже', 'Модификация_массива_во_время_итерации')}})</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Не существует способа остановить или прервать цикл <code>forEach()</code> кроме как выбрасыванием исключения. Если вам необходимо такое поведение, метод <code>forEach()</code> неправильный выбор.</p>
+
+<p>Досрочное прекращение может быть достигнуто с:</p>
+
+<ul>
+ <li>Простой цикл {{jsxref('Statements/for', 'for')}}</li>
+ <li>Циклы {{jsxref('Statements/for...of', 'for...of')}} / {{jsxref('Statements/for...in', 'for...in')}}</li>
+ <li>{{jsxref("Array.prototype.every()")}}</li>
+ <li>{{jsxref("Array.prototype.some()")}}</li>
+ <li>{{jsxref("Array.prototype.find()")}}</li>
+ <li>{{jsxref("Array.prototype.findIndex()")}}</li>
+</ul>
+
+<p>Если нужно протестировать элементы массива на условие и нужно вернуть булево значение, вы можете воспользоваться методами {{jsxref("Array.prototype.every()", "every()")}}, {{jsxref("Array.prototype.some()", "some()")}}, {{jsxref("Array.prototype.find()", "find()")}} или {{jsxref("Array.prototype.findIndex()", "findIndex()")}}.</p>
+
+<p>Метод <code>forEach()</code> выполняет функцию <code>callback</code> один раз для каждого элемента массива; в отличие от методов {{jsxref("Array.prototype.every()", "every()")}} и {{jsxref("Array.prototype.some()", "some()")}}, он всегда возвращает значение {{jsxref("Global_Objects/undefined", "undefined")}}.</p>
+</div>
+
+<h2 id="Examples" name="Examples">Примеры</h2>
+
+<h3 id="sparseArray" name="sparseArray">Нет операции для неинициализированных значений (разреженные массивы)</h3>
+
+<pre class="brush: js">const arraySparse = [1,3,,7]
+let numCallbackRuns = 0
+
+arraySparse.forEach((element) =&gt; {
+ console.log(element)
+ numCallbackRuns++
+})
+
+console.log("numCallbackRuns: ", numCallbackRuns)
+
+// 1
+// 3
+// 7
+// numCallbackRuns: 3
+// комментарий: как вы видите пропущенное значение между 3 и 7 не вызывало функцию callback.</pre>
+
+<h3 id="Конвертируем_цикл_for_в_forEach">Конвертируем цикл for в forEach</h3>
+
+<pre class="brush:js">const items = ['item1', 'item2', 'item3']
+const copy = []
+
+// до
+for (let i = 0; i &lt; items.length; i++) {
+ copy.push(items[i])
+}
+
+// после
+items.forEach(function(item){
+ copy.push(item)
+})
+</pre>
+
+<h3 id="Printing_the_contents_of_an_array" name="Printing_the_contents_of_an_array">Печать содержимого массива</h3>
+
+<div class="blockIndicator note">
+<p><strong>Примечание:</strong> Для отображения содержимого массива в консоли вы можете использовать <a href="/ru/docs/Web/API/Console/table" title="Отображает табличные данные в виде таблицы"><code>console.table()</code></a>, который выводит отформатированную версию массива.</p>
+
+<p>Следующий пример иллюстрирует альтернативный подход, использующий <code>forEach()</code>.</p>
+</div>
+
+<p>Следующий код выводит каждый элемент массива на новой строке журнала:</p>
+
+<pre class="brush: js">function logArrayElements(element, index, array) {
+ console.log('a[' + index + '] = ' + element);
+}
+
+// Обратите внимание на пропуск по индексу 2, там нет элемента, поэтому он не посещается
+[2, 5, , 9].forEach(logArrayElements);
+// логи:
+// a[0] = 2
+// a[1] = 5
+// a[3] = 9
+</pre>
+
+<h3 id="Использование_thisArg">Использование <code><var>thisArg</var></code></h3>
+
+<p>Следующий (надуманный) пример обновляет свойства объекта, когда перебирает записи массива:</p>
+
+<pre class="brush:js">function Counter() {
+ this.sum = 0
+ this.count = 0
+}
+Counter.prototype.add = function(array) {
+ array.forEach((entry) =&gt; {
+ this.sum += entry
+ ++this.count
+ }, this)
+ // ^---- Note
+}
+
+const obj = new Counter()
+obj.add([2, 5, 9])
+obj.count
+// 3
+obj.sum
+// 16
+</pre>
+
+<p>Поскольку в <code>forEach()</code>передан параметр <code><var>thisArg</var></code> (<code>this</code>), он затем передаётся в <code><var>callback</var></code> при каждом вызове. И callback использует его в качестве собственного значения <code>this</code>.</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Если при передаче callback функции используется {{jsxref('Functions/Arrow_functions', 'выражение стрелочной функции')}}, параметр <code><var>thisArg</var></code> может быть опущен, так как все стрелочные функции лексически привязываются к значению{{jsxref("Operators/this", "this")}}.</p>
+</div>
+
+<h3 id="Breaking_a_loop" name="Breaking_a_loop">Прерывание цикла</h3>
+
+<p>Следующий код использует {{jsxref("Array.prototype.every()")}} для логирования содержимого массива и останавливается при превышении значением заданного порогового значения <code>THRESHOLD</code>.</p>
+
+<pre class="brush: js">var THRESHOLD = 12;
+var v = [5, 2, 16, 4, 3, 18, 20];
+var res;
+
+res = v.every(function(element, index, array) {
+ console.log('element:', element);
+ if (element &gt;= THRESHOLD) {
+ return false;
+ }
+
+ return true;
+});
+console.log('res:', res);
+// логи:
+// element: 5
+// element: 2
+// element: 16
+// res: false
+
+res = v.some(function(element, index, array) {
+ console.log('element:', element);
+ if (element &gt;= THRESHOLD) {
+ return true;
+ }
+
+ return false;
+});
+console.log('res:', res);
+// логи:
+// element: 5
+// element: 2
+// element: 16
+// res: true
+</pre>
+
+<h3 id="An_object_copy_function" name="An_object_copy_function">Функция копирования объекта</h3>
+
+<p>Следующий код создаёт копию переданного объекта. Существует несколько способов создания копии объекта, и это один из них. Он позволяет понять, каким образом работает <code>Array.prototype.forEach()</code>, используя функции мета-свойств <code>Object.*</code> из ECMAScript 5.</p>
+
+<pre class="brush: js">function copy(o) {
+ var copy = Object.create(Object.getPrototypeOf(o));
+ var propNames = Object.getOwnPropertyNames(o);
+
+ propNames.forEach(function(name) {
+ var desc = Object.getOwnPropertyDescriptor(o, name);
+ Object.defineProperty(copy, name, desc);
+ });
+
+ return copy;
+}
+
+var o1 = { a: 1, b: 2 };
+var o2 = copy(o1); // теперь o2 выглядит также, как и o1
+</pre>
+
+<h3 id="Модификация_массива_во_время_итерации">Модификация массива во время итерации</h3>
+
+<p>В следующем примере в лог выводится <code>"one"</code>, <code>"two"</code>, <code>"four"</code>.</p>
+
+<p>При достижении записи, содержащей значение <code>'two'</code>, первая запись всего массива удаляется, в результате чего все оставшиеся записи перемещаются на одну позицию вверх. Поскольку элемент <code>'four'</code> теперь находится на более ранней позиции в массиве, <code>'three'</code> будет пропущен.</p>
+
+<p><code>forEach()</code> не делает копию массива перед итерацией.</p>
+
+<pre class="brush:js">let words = ['one', 'two', 'three', 'four']
+words.forEach((word) =&gt; {
+ console.log(word)
+ if (word === 'two') {
+ words.shift()
+ }
+})
+// one
+// two
+// four
+</pre>
+
+<h3 id="Выравнивание_уплощение_массива">Выравнивание (уплощение) массива</h3>
+
+<p>Следующий пример приведен только для целей обучения. Если вы хотите выравнять массив с помощью встроенных методов, вы можете использовать {{jsxref("Array.prototype.flat()")}}</p>
+
+<pre class="brush: js">function flatten(arr) {
+ const result = []
+
+ arr.forEach((i) =&gt; {
+ if (Array.isArray(i)) {
+ result.push(...flatten(i))
+ } else {
+ result.push(i)
+ }
+ })
+
+ return result
+}
+
+// Usage
+const nested = [1, 2, 3, [4, 5, [6, 7], 8, 9]]
+
+flatten(nested) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
+</pre>
+
+<h2 id="Polyfill" name="Polyfill">Полифилл</h2>
+
+<p>Метод <code>forEach()</code> был добавлен к стандарту ECMA-262 в 5-м издании; поэтому он может отсутствовать в других реализациях стандарта. Вы можете работать с ним, добавив следующий код в начало ваших скриптов, он позволяет использовать <code>forEach()</code> в реализациях, которые не поддерживают этот метод. Этот алгоритм является точно тем, что описан в ECMA-262 5-го издания; он предполагает, что {{jsxref("Object")}} и {{jsxref("TypeError")}} имеют свои первоначальные значения и что <code>callback.call</code> вычисляется в оригинальное значение {{jsxref("Function.prototype.call()")}}.</p>
+
+<pre class="brush: js">// Шаги алгоритма ECMA-262, 5-е издание, 15.4.4.18
+// Ссылка (en): http://es5.github.io/#x15.4.4.18
+// Ссылка (ru): http://es5.javascript.ru/x15.4.html#x15.4.4.18
+if (!Array.prototype.forEach) {
+
+ Array.prototype.forEach = function (callback, thisArg) {
+
+ var T, k;
+
+ if (this == null) {
+ throw new TypeError(' this is null or not defined');
+ }
+
+ // 1. Положим O равным результату вызова ToObject passing the |this| value as the argument.
+ var O = Object(this);
+
+ // 2. Положим lenValue равным результату вызова внутреннего метода Get объекта O с аргументом "length".
+ // 3. Положим len равным ToUint32(lenValue).
+ var len = O.length &gt;&gt;&gt; 0;
+
+ // 4. Если IsCallable(callback) равен false, выкинем исключение TypeError.
+ // Смотрите: http://es5.github.com/#x9.11
+ if (typeof callback !== 'function') {
+ throw new TypeError(callback + ' is not a function');
+ }
+
+ // 5. Если thisArg присутствует, положим T равным thisArg; иначе положим T равным undefined.
+ if (arguments.length &gt; 1) {
+ T = thisArg;
+ }
+
+ // 6. Положим k равным 0
+ k = 0;
+
+ // 7. Пока k &lt; len, будем повторять
+ while (k &lt; len) {
+
+ var kValue;
+
+ // a. Положим Pk равным ToString(k).
+ // Это неявное преобразование для левостороннего операнда в операторе in
+ // b. Положим kPresent равным результату вызова внутреннего метода HasProperty объекта O с аргументом Pk.
+ // Этот шаг может быть объединён с шагом c
+ // c. Если kPresent равен true, то
+ if (k in O) {
+
+ // i. Положим kValue равным результату вызова внутреннего метода Get объекта O с аргументом Pk.
+ kValue = O[k];
+
+ // ii. Вызовем внутренний метод Call функции callback с объектом T в качестве значения this и
+ // списком аргументов, содержащим kValue, k и O.
+ callback.call(T, kValue, k, O);
+ }
+ // d. Увеличим k на 1.
+ k++;
+ }
+ // 8. Вернём undefined.
+ };
+}
+</pre>
+
+<h2 id="Specifications" name="Specifications">Спецификации</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Спецификация</th>
+ <th scope="col">Статус</th>
+ <th scope="col">Комментарии</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES5.1', '#sec-15.4.4.18', 'Array.prototype.forEach')}}</td>
+ <td>{{Spec2('ES5.1')}}</td>
+ <td>Изначальное определение. Реализована в JavaScript 1.6.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES6', '#sec-array.prototype.foreach', 'Array.prototype.forEach')}}</td>
+ <td>{{Spec2('ES6')}}</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-array.prototype.foreach', 'Array.prototype.forEach')}}</td>
+ <td>{{Spec2('ESDraft')}}</td>
+ <td></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2>
+
+<div>
+<div class="hidden">Таблица совместимости на этой странице создается из структурированных данных. Если вы хотите внести свой вклад, ознакомьтесь с <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> и отправить нам pull request.</div>
+
+<p>{{Compat("javascript.builtins.Array.forEach")}}</p>
+</div>
+
+<h2 id="See_also" name="See_also">Смотрите также</h2>
+
+<ul>
+ <li>{{jsxref("Array.prototype.find()")}}</li>
+ <li>{{jsxref("Array.prototype.findIndex()")}}</li>
+ <li>{{jsxref("Array.prototype.map()")}}</li>
+ <li>{{jsxref("Array.prototype.every()")}}</li>
+ <li>{{jsxref("Array.prototype.some()")}}</li>
+ <li>{{jsxref("Map.prototype.forEach()")}}</li>
+ <li>{{jsxref("Set.prototype.forEach()")}}</li>
+</ul>