DEV Community

Discussion on: Stop abusing .map()!

Collapse
 
totally_chase profile image
Phantz

It should be noted that forEach is no longer the only alternative. Since ES7 or so, with the addition of methods like .entries on pretty much all collections, a for..of can do everything a forEach can.

Nailed the point in the head about map though. Mapping is not supposed to have side effects. A programmer should be able to know the gist of a higher order list operation by looking at the method call. When I see .map, I automatically assume it's a mapping. I don't want to find out later that it's actually modifying some external state. Seeing this kind of code smell in the wild is far too common, unfortunately.

Collapse
 
pitops profile image
Petros Kyriakou

.entries should be used sparingly as its performance is bad for large collections. The fastest being for loop.

Collapse
 
totally_chase profile image
Phantz • Edited

Actually, I was referring to the newer .entries methods. You know, Array.prototype.entries, Set.prototype.entries, Map.prototype.entries etc. They all return iterators and will not be slow.

Meanwhile the old and outdated Object.entries goes over the entire collection to build and return the array, which will then be iterated over by the user again. A truly unfortunate state. But hey, at least they are on the right path on the modern .entries impls!

Since we're on the topic, here's an efficient Object.entries impl instead-

function* objEntries<T>(x: Record<string, T>): IterableIterator<[string, T]> {
  for (const k in x) {
    yield [k, x[k]];
  }
}
Enter fullscreen mode Exit fullscreen mode

playground

Thread Thread
 
pitops profile image
Petros Kyriakou

yes i thought you were talking about Object.entries

Collapse
 
bugenzi profile image
Amar Bugarin

Can you elaborate on the performance part?

Collapse
 
shanoaice profile image
Andy Chen

It is quite true that functional approaches in JS are generally slower than the imperative approach, but I do think that it improves readability of the code and the performance overhead can usually be ignored......

Thread Thread
 
ashleyjsheridan profile image
Ashley Sheridan

Performance overhead can absolutely be ignored... if you don't care about the majority of your users. Usage is moving more and more to mobile devices, which are less powerful than desktops and laptops. They are also battery powered, and the more work the mobile browsers are being asked to do, the more it eats into that battery life.

Is readability of the code (and map is really no more readable than a foreach) really more important than the user base of the final product?

Collapse
 
davidmaxwaterman profile image
Max Waterman

IMO, you should move as much code into the js engine, and using js looping constructs does not do that. Also, for loops are...not as simple as you might have thought...they have been completely screwed up by the people who decide what JS/ES is:

youtube.com/watch?v=Nzokr6Boeaw

Before, they used to be one of the simplest and most elementary ways to loop.
In JavaScript, now, I never use them. Frankly, these days, there's always something better.

Why couldn't they just do this:

// for( a; b, c ) { d }
{
  a;
  while (b) {
    d;
    c;
  }
}
Enter fullscreen mode Exit fullscreen mode

Assuming I got that correct - you get the idea anyway.

Collapse
 
lethanhtupk profile image
Tu Le Thanh • Edited

Could you please tell what is the properly way to have side effects with each element in an array? I currently using side effects with map and promise.all

Collapse
 
totally_chase profile image
Phantz

Could you give an example of the usage that you need clarification with? Generally, if you're iterating over an array purely to perform side effects and are not interested in building a new array after mapping a function on each element - you would use a regular for..of loop.

Collapse
 
tanth1993 profile image
tanth1993

developer.mozilla.org/en-US/docs/W...
in this site, you will see, map function calls the callback() as synchronous function.
Therefore, there is no side effect items will be resolved.
You can use for or for... of to solve side-effect arrays