Understanding JavaScript's map()
JavaScript’s map
function is extremely useful, but it can also be a bit confusing when you’re just starting out with programming.
So here’s a breakdown of what it does exactly, and how to use it.
And by the way, if you need to catch up on JavaScript itself, I suggest you check out our JavaScript Primer first.
map() vs Map()
Note that this article is about the Array.map()
method, not the new Map
object.
The Definition
First, let’s start with the Mozilla Developer Network’s own definition:
The map() method creates a new array with the results of calling a provided function on every element in this array.
There’s a lot to unpack here! Before we start trying to understand this sentence, let’s try and isolate the different characters in this little story:
The map() method creates a new array with the results of calling a provided function on every element in this array.
As you can see, we have five different types of objects:
- An array
- The elements contained within this array
- A function
- The results returned by this function
- A new array
Looking at it this way, we can start to see what’s going on. map
is a function that:
- Takes an array and a function
- Applies the function to every element in the array
- Keeps track of the results of each successive function call
- Returns a new array containing these results
In the physical world, a map is a way of projecting a surface (terrain) onto another (paper). Similarly, the map
function “projects” the original array into the new one.
Calling map
Now I’ve said that map
takes two arguments, an array and a function. Usually, this is how you would call a function with two arguments:
map(myArray, myFunction);
But map
is defined as an array method, meaning it’s an action that any JavaScript array can perform on itself. So instead, we call it like this:
myArray.map(myFunction);
This of course presupposes you’ve written a myFunction
function somewhere else. Which brings us to the next topic.
The map
Callback
The function taken as argument by map
is known as the callback, because it’s called on every element in the original array.
And you have to write it in a very specific manner. The callback has to:
- Take in the current element being processed as argument.
- Return the new element that’s going to take its place in the new array.
Optionally, the function can also take in a second index
argument corresponding to the index (i.e. place in the array) of the current element, and a third array
argument pointing back to the original array.
Here’s a full example:
incrementByOne = function (element) {
return element + 1;
}
myArray = [1,2,3,4];
myArray.map(incrementByOne); // returns [2,3,4,5]
map
vs forEach
Before we move on, let’s address a common source of confusion: the difference between map
and its close cousin, forEach
. forEach
is defined as:
The forEach() method executes a provided function once per array element.
Notice what’s missing? forEach
doesn’t return anything. It calls a function once per element, but doesn’t do anything with the results of these calls.
This means forEach
is best used for situations where you don’t need a new, modified array in return. For example, if you wanted to alert
out the contents of an array:
myArray = [1,2,3,4];
myArray.forEach(alert);
Anonymous Functions
So far we’ve had to separately define our callback function for every map
. But JavaScript provides a handy shorthand in the form of anonymous functions.
Instead of defining the callback by itself, we define it inside the map
:
myArray = [1,2,3,4];
myArray.map(function (element) {
return element + 1;
});
Introducing ES2015
Recently, JavaScript introduced a new, shorter syntax to define anonymous functions, known as the “fat arrow” ES2015 (or ES6) syntax.
It lets you replace the traditional function (argument) {...}
syntax with the much shorter:
(argument) => {...}
And if you’re only taking in a single argument, you can even get rid of the ()
altogether:
argument => {...}
This lets us rewrite our previous snippet as:
myArray = [1,2,3,4];
myArray.map(element => {
return element + 1;
});
What’s more, if all you’re doing is returning a value you can shorten your code even further:
myArray.map(element => element + 1);
Whatever comes right after the arrow will be returned by the function.
map
in React
React uses a syntax called JSX to make outputting HTML easier. You can basically think of it as HTML with little bits of JavaScript sprinkled throughout:
<h3>Hello {["w", "o", "r", "l", "d"].join("")}</h3>
As you can see, whatever’s contained between curly brackets is evaluated as JavaScript, and the result of this evaluation is included in the JSX.
Now unlike templating languages like Handlebars or HAML, JSX doesn’t come with a built-in each
helper. Instead, when you want to loop over an array you use our good old friend map
.
So we’ll map the myList
array to a function that takes in an element, and returns a bit of JSX that wraps it in an <li>
tag:
<ul>
{myList.map(function (element) {
return (
<li>{element}</li>
)
})}
</ul>
Or, using the “fat arrow” syntax:
<ul>
{myList.map(element => <li>{element}</li>)}
</ul>
(We can get rid of the ()
because our JSX expression fits on a single line.)
Conclusion
map
is a very useful concept to master, so it’s well worth taking the time to understand it. Hopefully, this short guide will help you make sense of it and you too will soon be map
ping arrays left and right!
Image Credits: Map To The Golden Monkey, Hearthstone.
Comments
comments powered by Disqus