Recently watching this video with a study group, and working through a few of the coding challenges.
Callbacks and Higher-Order Functions
The reference link for this section is csbin.io/callbacks where the examples and instructions are given. I’m not going to repeat all that here, but I’m going to track here my own work in developing the answers, and my own thoughts and notes.
The first handful of challenges weren’t for me, to the point I didn’t have to think how these would be implemented. For someone new to this, though, the can be quite challenging, and we had some good discussion amongst my study buddies.
Map returns a new array, where each item is the result of running the callback on each element of the orginal array
Let’s check it: pass in an array of integers, and a function to add 2 to each element
Note the declaration and assignment of the current array item to the intermediate variable
item in the
for loop. This is not necesary by any means, but I put it in to illustrate the distinction between the item, and what’s acting on the item. This might become more useful in understanding when we begin to use
mapWith and others below.
The standard for loop used above in the
map function is great and all, and I’ll be using it again here implementing this
forEach function. The
forEach function will then become the building block for the next set of of functions.
forEach function is an impure function, returning nothing and only performing side-effects for each element of the array.
This also illustrates the fact we can pass functions and methods as regular parameters. This is the building block of functional programming.
The callback function
cb in the
forEach function has a particular signature:
It is passed the current element of the array in the
item parameter, and performs some action upon it. The callback may return a value, but it doesn’t necessarily have to. The next subsection requires the callback to return a value, so it’s is highly dependent on the specific use. Sometimes the only thing that you may want to have happen to the array elements is run a side effect, perhaps if your array is a set of hooks or other callback functions.
To illustrate the latter, suppose the array was a collection of line items on an order, and you wanted to calculate the line price based on the unit price and quantity of items. Since each line item is a self-contained object, updating that line price is a side-effect on that object, instead of creating new objects. This might be how it could be written:
map from above, this time using our
forEach method. This was a head-scratcher for some of the study buddies, so I’ll walk through it a little more slowly.
The main structure will still be the same:
- declare and initialize a space to build the new array
- inside the “loop” (which is implemented by the
forEach), I’ll push the result of the callback on the array item onto the new array variable
- return the new array
The key is to figure out how to provide the
forEach call. The parameters to
arr - the input array, and
cb the function to run on each. So inside, I need to create a function that will perform the
The anonymous function in the
forEach call takes in the current array item and performs the push onto the new array after calling the callback on the item. Here is the entire contstruction, redone with ES6 syntax for the anonymous function:
This works with
forEach’s side-effect-only behaviour because
mapped is declared outside the
forEach call. It is still within the scope of
mapWith, however, so it won’t leak anything, and
mapWith is itself a pure function.
forEach function body for
mapWith is the same as the original
map function, from after the
The result is the same as for
Continuing the discussion about whether our callbacks should return a value, in the case of the
mapWith (or even
map) functions, the callback must return a value, otherwise the new array will contain a collection of
(To be continued)
As the study group gets further, I’ll add more to this post.