Source code that is simple to read and understand is less likely to have hidden bugs.
A great advice given in the blog post avoid forEach is to use specific semantic array iterators
like map, filter, some instead of generic forEach. For example, when we want to
construct new array with every item passed through a function double, a preferred way is
to use map rather than forEach
1 | function double(x) { return x*2; } |
Compare this to the same result using forEach, which requires extra variable.
1 | var c = []; |
The semantic meaning of transform can only be inferred from reading its source code and then looking
at the initialization of c above.
Unfortunately, this is not the end of the story. Array.prototype.map can still have side effects, even
in simplest cases. For example, the callback function double can modify the original array!
1 | function double(x, k, array) { |
How do we guarantee that map does not modify the original array? The simplest solution is
to use immutable data structures. For example, seamless-immutable wraps native JavaScript data
structures and guarantees the original data structure remains unchanged.
1 | // same function double from above |
Notice that despite using the same callback function, the original Immutable object c remains
unchanged after c.map call. We can observe this better by printing the array passed into double
1 | function double(x, k, array) { |
Despite changing the passed data structure using array[k] = 0; statement, each iteration
receives the unchanged array [1, 2, 3]. The updates are silently ignored. If we execute the same
code in strict mode, trying to change the immutable data structure will generate a TypeError
1 | ; |
When using immutable data structures instead of JavaScript native objects, our code
and data flow becomes easier to understand and reason. map, some, filter, etc methods
always return a new object, leaving the original array unchanged.
There are several immutable data libraries for JavaScript. I like seamless-immutable for its API compatible with JavaScript built-in objects and arrays. Other libraries, like immutable provide larger API with more methods, but might require more changed to use them.