Skip to content

Commit

Permalink
update(JS): web/javascript/reference/global_objects/array/foreach (#985)
Browse files Browse the repository at this point in the history
* update(JS): web/javascript/reference/global_objects/array/foreach

* Apply suggestions from code review

Co-authored-by: Mykola Myslovskyi <[email protected]>

Co-authored-by: Mykola Myslovskyi <[email protected]>
  • Loading branch information
undead404 and AdriandeCita authored Nov 28, 2022
1 parent 581e17b commit 5bdb17c
Showing 1 changed file with 25 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,88 +41,59 @@ 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).

### Результат

`undefined`.

## Опис

Метод `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).

## Приклади

Expand Down

0 comments on commit 5bdb17c

Please sign in to comment.