From 5bdb17c4e245eabc4b65a44968d4cdbd81bff674 Mon Sep 17 00:00:00 2001 From: Vitalii Perehonchuk Date: Mon, 28 Nov 2022 23:36:15 +0200 Subject: [PATCH] update(JS): web/javascript/reference/global_objects/array/foreach (#985) * update(JS): web/javascript/reference/global_objects/array/foreach * Apply suggestions from code review Co-authored-by: Mykola Myslovskyi Co-authored-by: Mykola Myslovskyi --- .../global_objects/array/foreach/index.md | 79 ++++++------------- 1 file changed, 25 insertions(+), 54 deletions(-) diff --git a/files/uk/web/javascript/reference/global_objects/array/foreach/index.md b/files/uk/web/javascript/reference/global_objects/array/foreach/index.md index 8ebc6cbc5b..2c74c11527 100644 --- a/files/uk/web/javascript/reference/global_objects/array/foreach/index.md +++ b/files/uk/web/javascript/reference/global_objects/array/foreach/index.md @@ -41,19 +41,19 @@ forEach(function(element, index, array) { /* … */ }, thisArg) - `callbackFn` - - : Функція, яку буде викликано на кожному елементі. + - : Функція до виконання для кожного елемента масиву. Її повернене значення - відкидається. Ця функція викликається із наступними аргументами: - `element` - : Поточний елемент масиву, який опрацьовується. - `index` - - : Порядковий номер цього елементу в масиві. + - : Індекс поточного елемента масиву, що опрацьовується. - `array` - : Власне масив, на якому було викликано `forEach()`. - `thisArg` {{optional_inline}} - - : Значення, яке буде підставлено як `this` під час виконання `callbackFn`. + - : Значення для використання за `this` при виконанні `callbackFn`. Докладніше про це в [ітеративних методах](/uk/docs/Web/JavaScript/Reference/Global_Objects/Array#iteratyvni-metody). ### Результат @@ -61,68 +61,39 @@ forEach(function(element, index, array) { /* … */ }, thisArg) ## Опис -Метод `forEach()` викликає подану функцію `callbackFn` один раз для кожного елементу в масиві, у порядку зростання їх порядкового номера. +Метод `forEach()` є [ітеративним методом](/uk/docs/Web/JavaScript/Reference/Global_Objects/Array#iteratyvni-metody). Він викликає передану функцію `callbackFn` на кожному елементі масиву, в порядку зростання індексів. На відміну від {{jsxref("Array.prototype.map()", "map()")}}, `forEach()` завжди повертає {{jsxref("undefined")}} і не може бути проміжною ланкою ланцюжка. Типове його використання – для виконання побічних ефектів у кінці ланцюжка. `callbackFn` закликається лише для тих індексів масиву, що мають присвоєні значення. Вона не закликається для порожніх комірок у [розріджених масивах](/uk/docs/Web/JavaScript/Guide/Indexed_collections#rozridzheni-masyvy). -Функція `callbackFn` викликається з трьома аргументами: +`forEach()` не видозмінює масиву, на котрому його викликали, але функція, передана як `callbackFn`, може це робити. Проте слід звернути увагу, що довжина масиву запам'ятовується _до_ першого заклику `callbackFn`. Таким чином: -1. значення елементу -2. порядковий номер елементу -3. масив, на котрому викликано `forEach` - -Якщо у `forEach()` задано параметр `thisArg`, його буде використано як значення `this` у функції зворотного виклику. В загальному випадку значення `this`, яке бачитиме функція `callback`, визначається згідно з [загальними правилами визначення значення `this`, доступного для функції](/uk/docs/Web/JavaScript/Reference/Operators/this). - -Діапазон елементів, що опрацьовуються функцією `forEach()`, задається до першого виклику `callbackFn`. Елементи, які будуть присвоєні за індексами, що вже перебрані методом, або ж до індексів за межами цього діапазону, не будуть опрацьовані функцією `callbackFn`. Якщо наявні елементи змінюються чи видаляються, то до `callbackFn` буде передано їх фактичне значення на момент, коли функція `forEach()` їх опрацьовує. Ті елементи, які були видалені до того, як їх опрацювала функція, опрацьовані не будуть. Якщо елементи, які уже були опрацьовані, видаляються (наприклад, за допомогою {{jsxref("Array.prototype.shift()", "shift()")}}) під час проходження по масиву, наступні елементи буде пропущено. ([Дивіться цей приклад нижче](#zmina-masyvu-pid-chas-perebyrannia-yoho-elementiv).) +- `callbackFn` не оброблятиме жодних елементів, доданих поза початковою довжиною масиву, відколи почався виклик `forEach()`. +- Зміни за вже обробленими індексами не призводять до повторного заклику на них `callbackFn`. +- Якщо наявний, іще не оброблений елемент масиву вже був змінений `callbackFn`, то його значення, передане в `callbackFn`, буде значенням на ту мить, коли такий елемент обробляється. [Видалені](/uk/docs/Web/JavaScript/Reference/Operators/delete) елементи – не обробляються. > **Застереження:** Одночасні модифікації такого типу, як описано в попередньому абзаці, часто приводять до коду, який важко зрозуміти. Загалом заведено уникати такого запису (крім особливих випадків). -Метод `forEach()` виконує функцію `callbackFn` один раз для кожного елементу в масиві, і на відміну від {{jsxref("Array.prototype.map()", "map()")}} чи -{{jsxref("Array.prototype.reduce()", "reduce()")}} він завжди повертає значення {{jsxref("undefined")}} і не придатний для ланцюгових викликів. Зазвичай його використовують для виконання побічних ефектів наприкінці ланцюжка викликів. +Метод `forEach()` є [узагальненим](/uk/docs/Web/JavaScript/Reference/Global_Objects/Array#uzahalneni-metody-masyvu). Він лишень очікує, що значення `this` матиме властивість `length`, а також властивості з цілочисловими ключами. -Метод `forEach()` не змінює масив, на якому він викликається. (Хоча -`callbackFn` може це робити) +Немає іншого способу зупинити чи перервати цикл `forEach()`, окрім викидання винятку. Якщо потрібна логіка з перериванням, то метод `forEach()` – негодящий інструмент. -Метод `forEach()` є [узагальненим](/uk/docs/Web/JavaScript/Reference/Global_Objects/Array#uzahalneni-metody-masyvu). Він лишень очікує, що значення `this` матиме властивість `length`, а також властивості з цілочисловими ключами. +Раннього завершення можна досягнути з інструкціями циклів, як то [`for`](/uk/docs/Web/JavaScript/Reference/Statements/for), [`for...of`](/uk/docs/Web/JavaScript/Reference/Statements/for...of) і [`for...in`](/uk/docs/Web/JavaScript/Reference/Statements/for...in). Методи масивів, як то {{jsxref("Array/every", "every()")}}, {{jsxref("Array/some", "some()")}}, {{jsxref("Array/find", "find()")}} і {{jsxref("Array/findIndex", "findIndex()")}, також відразу зупиняють ітерацію, коли подальше ітерування стає непотрібним. -> **Примітка:** Не існує способу зупинити або перервати цикл `forEach()` окрім -> як шляхом викидання винятку. Якщо вам потрібна можливість перервати цикл, метод `forEach()` -> для цього не підходить. -> -> Зупинка циклу до його завершення може бути досягнена шляхом використання: -> -> - Простого циклу [for](/uk/docs/Web/JavaScript/Reference/Statements/for) -> - Циклів [for...of](/uk/docs/Web/JavaScript/Reference/Statements/for...of) -> або [for...in](/uk/docs/Web/JavaScript/Reference/Statements/for...in) -> - {{jsxref("Array.prototype.every()")}} -> - {{jsxref("Array.prototype.some()")}} -> - {{jsxref("Array.prototype.find()")}} -> - {{jsxref("Array.prototype.findIndex()")}} -> -> Методи масиву, як от {{jsxref("Array.prototype.every()", "every()")}}, -> {{jsxref("Array.prototype.some()", "some()")}}, {{jsxref("Array.prototype.find()", "find()")}} і {{jsxref("Array.prototype.findIndex()", "findIndex()")}}, перевіряють -> елементи масиву за допомогою предикату, що повертає істинне значення, якщо -> продовження перебирання масиву є необхідним. +`forEach()` розраховує на синхронну функцію: він не очікує на проміси. Слід взяти до уваги можливі наслідки при використанні промісів (чи асинхронних функцій) у функціях зворотного виклику для `forEach`. -> **Примітка:** `forEach` приймає синхронну функцію. -> -> `forEach` не чекає на завершення промісів. Впевніться, що ви розумієте можливі наслідки -> передачі промісів (чи асинхронних функцій) в аргументах функції `forEach`. -> -> ```js -> const ratings = [5, 4, 5]; -> let sum = 0; -> -> const sumFunction = async (a, b) => a + b; -> -> ratings.forEach(async (rating) => { -> sum = await sumFunction(sum, rating); -> }); -> -> console.log(sum); -> // Наївно очікуваний вивід: 14 -> // Фактичний вивід: 0 -> ``` +```js +const ratings = [5, 4, 5]; +let sum = 0; +const sumFunction = async (a, b) => a + b; +ratings.forEach(async (rating) => { + sum = await sumFunction(sum, rating); +}); +console.log(sum); +// Наївно очікуваний вивід: 14 +// Фактичний вивід: 0 +``` + +Про виконання низки асинхронних операцій, послідовно чи паралельно, дивіться [композицію промісів](/uk/docs/Web/JavaScript/Guide/Using_promises#kompozytsiia). ## Приклади