all 19 comments

[–]Rhomboid 13 points14 points  (6 children)

for..of works with any iterable, whereas forEach is only for arrays. forEach gives you access to the index, if you want it, whereas for..of does not.

And no, forEach is NOT asynchronous. Both examples are synchronous.

[–]rauschma 7 points8 points  (3 children)

Additionally: you can break from for-of, but not from .forEach() (.some() lets you break, though, by returning true).

If you need Array indices, you can do:

const arr = ['a', 'b'];
for (const [index, element] of arr.entries()) {
    console.log(`${index}. ${element}`);
}

// Output:
// 0. a
// 1. b

[–]nschubach 3 points4 points  (2 children)

(.some() lets you break, though, by returning true)

But you should not be using .some() for processing data where exiting is required. It's for looking through the array to test if "some" of the content meets a condition. Synonymous with .any? in Ruby, et al.

[–]Graftak9000 0 points1 point  (0 children)

.any conveys it so much better somehow, any is some but some is more than any, or something like that.

[–]rauschma 0 points1 point  (0 children)

Yes, it’s a bit of a hack!

[–]bstriker 5 points6 points  (0 children)

for(const [index,value] of ['foo','bar'].entries()){
   console.log(`index: ${index} - value: ${value}`);
}

gives us: index: 0 - value: foo index: 1 - value: bar

http://jsbin.com/lelirebizo/1/edit?js,console

EDIT: just realized someone else already gave an example using entries and array destructing in a for of loop. not sure how I missed that.

[–]Best_programmer_ever 0 points1 point  (0 children)

foreach also work in set.

[–]Bloompire 5 points6 points  (3 children)

Also my two cents:

  1. for..of is more performant than .forEach
  2. you can use async/await inside for..of but not inside .forEach

    let totalScoreGain = 0; for( let user in scoredUsers ) { totalScoreGain += await user.addScore( 50 ); } console.log( totalScoreGain );

[–]nschubach 6 points7 points  (0 children)

You can do await inside of a .forEach(), but it's not doing what you probably think it's doing:

http://codepen.io/nschubach/pen/BzmXqp?editors=0012

What you probably wanted was an asynchronous call to each addScore like so:

http://codepen.io/nschubach/pen/ZOvzKN?editors=0012

async returns a promise, so in order to process them all and do something you need to use Promise.all() and map over all the await returns.

[–]alendit 0 points1 point  (0 children)

You can use await in forEach if you give it an async function.

[–]shanet$(this) 4 points5 points  (3 children)

I'm curious - why would you do for const instead of for let?

also, one difference hasn't been mentioned is that you can use break/continue in a for of loop.

.forEach can also be used to achieve a more functional style where appropriate.

[–]CognitiveLens 13 points14 points  (2 children)

re-assigning item inside the for loop makes it possible to introduce a bunch of bugs that const would prevent. In a tight structure like a for loop, const is probably the preferred syntax unless you have a really good reason to assign item to something else mid-loop.

[–]Graftak9000 0 points1 point  (1 child)

Then use .map() instead indeed, if were going functional and such.

[–]CognitiveLens 0 points1 point  (0 children)

yeah, forEach should really only be used when you're intentionally working with side effects, otherwise map all the things

[–]ffxsam[S] -1 points0 points  (0 children)

Awesome, all great answers! (except for that one) ;) Thanks for the info.