Skip to content

Commit c499422

Browse files
authored
Improve .forEach examples: syntax and consistency (#12799)
* Improve .forEach examples: syntax and consistency * fixup! Improve .forEach examples: syntax and consistency * fixup! Improve .forEach examples: syntax and consistency * Remove Polyfill section Array.prototype.forEach
1 parent be7254c commit c499422

File tree

1 file changed

+63
-144
lines changed
  • files/en-us/web/javascript/reference/global_objects/array/foreach

1 file changed

+63
-144
lines changed

files/en-us/web/javascript/reference/global_objects/array/foreach/index.md

Lines changed: 63 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ for each array element.
2222

2323
```js
2424
// Arrow function
25-
forEach((element) => { /* ... */ } )
26-
forEach((element, index) => { /* ... */ } )
27-
forEach((element, index, array) => { /* ... */ } )
25+
forEach((element) => { /* ... */ })
26+
forEach((element, index) => { /* ... */ })
27+
forEach((element, index, array) => { /* ... */ })
2828

2929
// Callback function
3030
forEach(callbackFn)
@@ -125,109 +125,34 @@ effects at the end of a chain.
125125
> implications while using promises (or async functions) as `forEach` callback.
126126
>
127127
> ```js
128-
> let ratings = [5, 4, 5];
128+
> const ratings = [5, 4, 5];
129129
> let sum = 0;
130130
>
131-
> let sumFunction = async function (a, b)
132-
> {
133-
> return a + b
134-
> }
131+
> const sumFunction = async (a, b) => a + b;
135132
>
136-
> ratings.forEach(async function(rating) {
137-
> sum = await sumFunction(sum, rating)
138-
> })
133+
> ratings.forEach(async (rating) => {
134+
> sum = await sumFunction(sum, rating);
135+
> });
139136
>
140-
> console.log(sum)
137+
> console.log(sum);
141138
> // Naively expected output: 14
142139
> // Actual output: 0
143140
> ```
144141
145-
## Polyfill
146-
147-
`forEach()` was added to the ECMA-262 standard in the 5th
148-
edition, and it may not be present in all implementations of the standard. You can work
149-
around this by inserting the following code at the beginning of your scripts, allowing
150-
use of `forEach()` in implementations which do not natively support it.
151-
152-
This algorithm is exactly the one specified in ECMA-262, 5th edition,
153-
assuming {{jsxref("Object")}} and {{jsxref("TypeError")}} have their original values and
154-
that `fun.call` evaluates to the original value of
155-
{{jsxref("Function.prototype.call()")}}.
156-
157-
```js
158-
// Production steps of ECMA-262, Edition 5, 15.4.4.18
159-
// Reference: https://es5.github.io/#x15.4.4.18
160-
161-
if (!Array.prototype['forEach']) {
162-
163-
Array.prototype.forEach = function(callback, thisArg) {
164-
165-
if (this == null) { throw new TypeError('Array.prototype.forEach called on null or undefined'); }
166-
167-
var T, k;
168-
// 1. Let O be the result of calling toObject() passing the
169-
// |this| value as the argument.
170-
var O = Object(this);
171-
172-
// 2. Let lenValue be the result of calling the Get() internal
173-
// method of O with the argument "length".
174-
// 3. Let len be toUint32(lenValue).
175-
var len = O.length >>> 0;
176-
177-
// 4. If isCallable(callback) is false, throw a TypeError exception.
178-
// See: https://es5.github.io/#x9.11
179-
if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function'); }
180-
181-
// 5. If thisArg was supplied, let T be thisArg; else let
182-
// T be undefined.
183-
if (arguments.length > 1) { T = thisArg; }
184-
185-
// 6. Let k be 0
186-
k = 0;
187-
188-
// 7. Repeat, while k < len
189-
while (k < len) {
190-
191-
var kValue;
192-
193-
// a. Let Pk be ToString(k).
194-
// This is implicit for LHS operands of the in operator
195-
// b. Let kPresent be the result of calling the HasProperty
196-
// internal method of O with argument Pk.
197-
// This step can be combined with c
198-
// c. If kPresent is true, then
199-
if (k in O) {
200-
201-
// i. Let kValue be the result of calling the Get internal
202-
// method of O with argument Pk.
203-
kValue = O[k];
204-
205-
// ii. Call the Call internal method of callback with T as
206-
// the this value and argument list containing kValue, k, and O.
207-
callback.call(T, kValue, k, O);
208-
}
209-
// d. Increase k by 1.
210-
k++;
211-
}
212-
// 8. return undefined
213-
};
214-
}
215-
```
216-
217142
## Examples
218143
219144
### No operation for uninitialized values (sparse arrays)
220145
221146
```js
222-
const arraySparse = [1,3,,7]
223-
let numCallbackRuns = 0
147+
const arraySparse = [1, 3,, 7];
148+
let numCallbackRuns = 0;
224149
225-
arraySparse.forEach(function(element) {
226-
console.log(element)
227-
numCallbackRuns++
228-
})
150+
arraySparse.forEach((element) => {
151+
console.log({ element });
152+
numCallbackRuns++;
153+
});
229154
230-
console.log("numCallbackRuns: ", numCallbackRuns)
155+
console.log({ numCallbackRuns });
231156
232157
// 1
233158
// 3
@@ -239,18 +164,18 @@ console.log("numCallbackRuns: ", numCallbackRuns)
239164
### Converting a for loop to forEach
240165

241166
```js
242-
const items = ['item1', 'item2', 'item3']
243-
const copyItems = []
167+
const items = ['item1', 'item2', 'item3'];
168+
const copyItems = [];
244169

245170
// before
246171
for (let i = 0; i < items.length; i++) {
247-
copyItems.push(items[i])
172+
copyItems.push(items[i]);
248173
}
249174

250175
// after
251-
items.forEach(function(item){
252-
copyItems.push(item)
253-
})
176+
items.forEach((item) => {
177+
copyItems.push(item);
178+
});
254179
```
255180

256181
### Printing the contents of an array
@@ -265,13 +190,13 @@ items.forEach(function(item){
265190
The following code logs a line for each element in an array:
266191

267192
```js
268-
function logArrayElements(element, index, array) {
269-
console.log('a[' + index + '] = ' + element)
270-
}
193+
const logArrayElements = (element, index, array) => {
194+
console.log('a[' + index + '] = ' + element);
195+
};
271196

272197
// Notice that index 2 is skipped, since there is no item at
273198
// that position in the array...
274-
[2, 5, , 9].forEach(logArrayElements)
199+
[2, 5,, 9].forEach(logArrayElements);
275200
// logs:
276201
// a[0] = 2
277202
// a[1] = 5
@@ -288,19 +213,18 @@ function Counter() {
288213
this.sum = 0
289214
this.count = 0
290215
}
216+
291217
Counter.prototype.add = function(array) {
292218
array.forEach(function countEntry(entry) {
293-
this.sum += entry
294-
++this.count
295-
}, this)
296-
}
297-
298-
const obj = new Counter()
299-
obj.add([2, 5, 9])
300-
obj.count
301-
// 3
302-
obj.sum
303-
// 16
219+
this.sum += entry;
220+
++this.count;
221+
}, this);
222+
};
223+
224+
const obj = new Counter();
225+
obj.add([2, 5, 9]);
226+
console.log(obj.count); // 3
227+
console.log(obj.sum); // 16
304228
```
305229

306230
Since the `thisArg` parameter (`this`) is provided to
@@ -321,20 +245,18 @@ and is presented to explain how `Array.prototype.forEach()` works by using
321245
ECMAScript 5 `Object.*` meta property functions.
322246

323247
```js
324-
function copy(obj) {
325-
const copy = Object.create(Object.getPrototypeOf(obj))
326-
const propNames = Object.getOwnPropertyNames(obj)
327-
328-
propNames.forEach(function(name) {
329-
const desc = Object.getOwnPropertyDescriptor(obj, name)
330-
Object.defineProperty(copy, name, desc)
331-
})
332-
333-
return copy
334-
}
335-
336-
const obj1 = { a: 1, b: 2 }
337-
const obj2 = copy(obj1) // obj2 looks like obj1 now
248+
const copy = (obj) => {
249+
const copy = Object.create(Object.getPrototypeOf(obj));
250+
const propNames = Object.getOwnPropertyNames(obj);
251+
propNames.forEach((name) => {
252+
const desc = Object.getOwnPropertyDescriptor(obj, name);
253+
Object.defineProperty(copy, name, desc);
254+
});
255+
return copy;
256+
};
257+
258+
const obj1 = { a: 1, b: 2 };
259+
const obj2 = copy(obj1); // obj2 looks like obj1 now
338260
```
339261

340262
### Modifying the array during iteration
@@ -349,15 +271,15 @@ Because element `four` is now at an earlier position in the array,
349271
`forEach()` does not make a copy of the array before iterating.
350272

351273
```js
352-
let words = ['one', 'two', 'three', 'four']
353-
words.forEach(function(word) {
354-
console.log(word)
274+
const words = ['one', 'two', 'three', 'four'];
275+
words.forEach((word) => {
276+
console.log(word);
355277
if (word === 'two') {
356-
words.shift() //'one' will delete from array
278+
words.shift(); //'one' will delete from array
357279
}
358-
}) // one // two // four
280+
}); // one // two // four
359281

360-
console.log(words); //['two', 'three', 'four']
282+
console.log(words); // ['two', 'three', 'four']
361283
```
362284

363285
### Flatten an array
@@ -366,24 +288,21 @@ The following example is only here for learning purpose. If you want to flatten
366288
array using built-in methods you can use {{jsxref("Array.prototype.flat()")}}.
367289

368290
```js
369-
function flatten(arr) {
370-
const result = []
371-
372-
arr.forEach(function(i) {
291+
const flatten = (arr) => {
292+
const result = [];
293+
arr.forEach((i) => {
373294
if (Array.isArray(i)) {
374-
result.push(...flatten(i))
295+
result.push(...flatten(i));
375296
} else {
376-
result.push(i)
297+
result.push(i);
377298
}
378-
})
379-
380-
return result
299+
});
300+
return result;
381301
}
382302

383303
// Usage
384-
const nested = [1, 2, 3, [4, 5, [6, 7], 8, 9]]
385-
386-
flatten(nested) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
304+
const nested = [1, 2, 3, [4, 5, [6, 7], 8, 9]];
305+
console.log(flatten(nested)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
387306
```
388307

389308
## Specifications

0 commit comments

Comments
 (0)