What does `for element of arr` buy me over `arr.forEach(element => ...)`
I don't find the for...of syntax particularly appealing or useful, but I might be missing something. Is it a matter of preference?
What does `for element of arr` buy me over `arr.forEach(element => ...)`
I don't find the for...of syntax particularly appealing or useful, but I might be missing something. Is it a matter of preference?
function *myIterable (v) {
while(--v) yield v
}
let launchCountdown = myIterable(60)
for (let i of launchCountdown)
console.log(`t minus ${i} seconds`)
So in effect arrays can be thought of as iterables in ES6. So IMHO it allows for more consistent behavior with the way iterators in other languages like Java and C++arr.map(...).filter(...).forEach(...) which allows me to iterate over the filtered result? One would assign the result of filter to a variable and call for...of on that?
EDIT: Also, I never saw any mention of for...of working for object literals (à la `for (let [key, value] of obj`), I suppose that's out of scope, correct?
Just like that. It would be pretty nice to have generic filter/map that can work on arbitrary iterables, but we don't have that right now. :(
> Also, I never saw any mention of for...of working for object literals (à la `for (let [key, value] of obj`)
for (let [key, value] of Object.entries(obj)) {
}
it's not in "ES6"/ES2015, but it's in ES2017 drafts and is implemented in Chrome and Firefox but so far not elsewhere. The need to do Object.entries instead of obj.entries() is annoying, but needed in case your literal has a property named "entries"... There's also Object.keys() and Object.values(), of course. function* map(iterator, mapper) {
for (const elem of iterator) {
yield mapper(elem);
}
}
function* filter(iterator, filterer) {
for (const elem of iterator) {
if (filterer(elem)) {
yield elem;
}
}
}
function forEach(iterator, eacher) {
for (const elem of iterator) {
eacher(iterator);
}
}
function reduce(iterator, reducer, initial) {
let current = initial;
for (const elem of iterator) {
current = reducer(current, elem);
}
return current;
}break/return/throw work as expected.
I imagine (eventually if not already) for-of will be slightly more performant, but that's just a hunch.
Personally I find the for-of syntax more readable.
The lack of inner functions means that you can await during part of a loop without a bunch of fuckery with the inner function with forEach.
However, even in just arrays there is arguably a benefit. Namely, an extra function being created and invoked with forEach. While in a JITing compiler, the performance difference between for...of and forEach might be negligible (or non existent), you can't always be sure what the JIT is going to do. For hotspots, I would probably prefer for..of
In a JIT, forEach is actually _easier_ to optimize well (just need to inline the callback function, though of course that can fail for various reasons) than for-of (need to inline the calls to next() on the iterator, need to do escape analysis on the return value of next(), need to do scalar replacement on the return value of next; note that this is a strict superset of the work needed to optimize forEach).
for-of can be nicer to read, and can work on arbitrary iterables. Those are its key strengths. Performance just isn't, unfortunately.
[1] https://developer.mozilla.org/en/docs/Web/JavaScript/Referen...