Looping in Javascript and Typescript

Javascript and Typescript have way too many ways to iterate and loop over arrays, objects, and iterables. In this post I try to collect them and make some sense of them.

Construct | Effect on array | Effect on object | Effect on iterable (Map, Set)

for (let i=0;
i<obj.length;
i++)

★Iterates over indices

N/A

N/A

for x in obj | Iterates over indices and custom props (including prototype props), in random order(!) | ★Iterates over enumerable obj props (including prototype props) | Iterates over Map keys; doesn’t work for Set
for x of obj | ★Iterates over values (in order) | N/A [^notiterable] | ★Iterates over [key, value] for Map, elements for Set
obj.forEach(x => ...) | ★Iterates over values (also passes index & array to callback) [^nobreak] [^foreach-await] | N/A [^objforeach] | ★Map: iterates over values + keys [^nobreak]

Notes:

[^nobreak]: .forEach() has no way to break out from the middle of the loop; the others ways of iterating over an array or object support break and continue.

[^objforeach]: obj.forEach() does not work on an Object, but you can do Object.keys(obj).forEach(...). That gets the keys of the object as an array, and then loops over the array of keys.

[^notiterable]: gives this error: “Error: obj is not iterable”.

[^foreach-await]: arr.forEach() does not work properly with await calls in the callback, but the others support await in the body.