Cara menggunakan time to seconds javascript

Functional programming has been making quite a splash in the development world these days. And for good reason: Functional techniques can help you write more declarative code that is easier to understand at a glance, refactor, and test.

One of the cornerstones of functional programming is its special use of lists and list operations. Those things are exactly what they sound like: arrays of things and the stuff you do to them. But the functional mindset treats them a bit differently than you might expect.

How to Use Map, Filter, & Reduce in JavaScript

Cara menggunakan time to seconds javascript

This article will take a close look at what I like to call the "big three" list operations:

3
26,
3
27, and
3
28. Wrapping your head around these three functions is an important step towards being able to write clean, functional code, and it opens the doors to the vastly powerful techniques of functional and reactive programming.

Curious? Let's dive in.

A Map From List to List

Often, we find ourselves needing to take an array and modify every element in it in exactly the same way. Typical examples of this are squaring every element in an array of numbers, retrieving the name from a list of users, or running a regex against an array of strings.

3
26 is a method built to do exactly that. It's defined on
3
30, so you can call it on any array, and it accepts a callback as its first argument. 

The syntax for

3
26 is shown below.

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
  // return element for newArray, after executing something

3
}[, thisArg]);

When you call 

3
26 on an array, it executes that callback on every element within it, returning a new array with all of the values that the callback returned.

Under the hood, 

3
26 passes three arguments to your callback:

  1. the current item in the array
  2. the array index of the current item
  3. the entire array you called
    3
    26 on 

Let's look at some code.

326 in Practice

Suppose we have an app that maintains an array of your tasks for the day. Each 

3
36 is an object, each with a 
3
37 and 
3
38 property:

1
// Durations are in minutes 

2
const tasks = [
3
let newArray = arr.map(callback(currentValue[, index[, array]]) {
1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
3
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
let newArray = arr.map(callback(currentValue[, index[, array]]) {
5
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
7
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
let newArray = arr.map(callback(currentValue[, index[, array]]) {
1
2
0
2
1
2
2
2
3
2
4
let newArray = arr.map(callback(currentValue[, index[, array]]) {
7
2
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
1
2
8
2
9
  // return element for newArray, after executing something

0
  // return element for newArray, after executing something

1
  // return element for newArray, after executing something

2
  // return element for newArray, after executing something

3
  // return element for newArray, after executing something

4
  // return element for newArray, after executing something

5

Let's say we want to create a new array with just the name of each task, so we can take a look at everything we've done today. Using a

3
39 loop, we'd write something like this:

1
  // return element for newArray, after executing something

7
2
  // return element for newArray, after executing something

9
3
3
1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
3
3
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
3
5
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
3
8

JavaScript also offers a 

3
40 loop. It functions like a 
3
39 loop, but manages all the messiness of checking our loop index against the array length for us:

1
  // return element for newArray, after executing something

7
2
  // return element for newArray, after executing something

9
3
}[, thisArg]);
4
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
}[, thisArg]);
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
}[, thisArg]);
8
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
3
8

Using

3
26, we can simply write:

1
1
3
2
1
5
3
}[, thisArg]);
8
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
// Durations are in minutes 

0

Here I included the

3
43 and  
3
44 parameters to remind you that they're there if you need them. Since I didn't use them here, though, you could leave them out, and the code would run just fine.

An even more succinct way of writing

3
26 in modern JavaScript is with arrow functions.

1
// Durations are in minutes 

2
2
3
// Durations are in minutes 

5

Arrow functions are a short form for one-line functions that just have a

3
46 statement. It doesn't get much more readable than that.

There are a few important differences between the different approaches:

  1. Using
    3
    26, you don't have to manage the state of the
    3
    39 loop yourself.
  2. With
    3
    26, you can operate on the element directly, rather than having to index into the array.
  3. You don't have to create a new array and
    3
    50 into it.
    3
    26 returns the finished product all in one go, so we can simply assign the return value to a new variable.
  4. You do have to remember to include a 
    3
    46 statement in your callback. If you don't, you'll get a new array filled with
    3
    53. 

Turns out, all of the functions we'll look at today share these characteristics.

The fact that we don't have to manually manage the state of the loop makes our code simpler and more maintainable. The fact that we can operate directly on the element instead of having to index into the array makes things more readable. 

Using a 

3
40 loop solves both of these problems for us. But 
3
26 still has at least two distinct advantages:

  1. 3
    40 returns 
    3
    53, so it doesn't chain with other array methods. 
    3
    26 returns an array, so you can chain it with other array methods.
  2. 3
    26 returns an array with the finished product, rather than requiring us to mutate an array inside the loop. 

Keeping the number of places where you modify state to an absolute minimum is an important tenet of functional programming. It makes for safer and more intelligible code.

Gotchas

The callback you pass to 

3
26 must have an explicit 
3
46 statement, or 
3
26 will spit out an array full of 
3
53. It's not hard to remember to include a 
3
46 value, but it's not hard to forget. 

If you do forget, 

3
26 won't complain. Instead, it'll quietly hand back an array full of nothing. Silent errors like that can be surprisingly hard to debug. 

Fortunately, this is the only gotcha with 

3
26. But it's a common enough pitfall that I'm obliged to emphasize: Always make sure your callback contains a 
3
46 statement!

Implementation

Reading implementations is an important part of understanding. So let's write our own lightweight

3
26 to better understand what's going on under the hood. If you want to see a production-quality implementation, check out Mozilla's polyfill at MDN.

1
// Durations are in minutes 

7
2
// Durations are in minutes 

9
3
  // return element for newArray, after executing something

9
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
2
3
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
2
5
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
2
7
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
  // return element for newArray, after executing something

9
2
0
const tasks = [
1
2
2
const tasks = [
3

This code accepts an array and a callback function as arguments. It then creates a new array, executes the callback on each element on the array we passed in, pushes the results into the new array, and returns the new array. If you run this in your console, you'll get the same result as before. 

While we're using a for loop under the hood, wrapping it up into a function hides the details and lets us work with the abstraction instead. 

That makes our code more declarative—it says what to do, not how to do it. You'll appreciate how much more readable, maintainable, and, erm, debuggable this can make your code.

Filter Out the Noise

The next of our array operations is

3
27. It does exactly what it sounds like: It takes an array and filters out unwanted elements.

The syntax for filter is:

1
const tasks = [
5
2
const tasks = [
7
3
}[, thisArg]);

Just like

3
26,
3
27 passes your callback three arguments:

  1. the current item 
  2. the current index
  3. the array you called
    3
    27 on

Consider the following example, which filters out any string which is less than 8 characters.

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
01
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
03
3
let newArray = arr.map(callback(currentValue[, index[, array]]) {
05

The expected result will be:

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
07

Let's revisit our task example. Instead of pulling out the names of each task, let's say I want to get a list of just the tasks that took me two hours or more to get done.

Using

3
40, we'd write:

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
09
2
  // return element for newArray, after executing something

9
3
}[, thisArg]);
4
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
15
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
let newArray = arr.map(callback(currentValue[, index[, array]]) {
17
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
19
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
}[, thisArg]);
8
2
0
2
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
24
2
4
2
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
27
2
8
let newArray = arr.map(callback(currentValue[, index[, array]]) {
29
  // return element for newArray, after executing something

0
let newArray = arr.map(callback(currentValue[, index[, array]]) {
31

With

3
27, we can simply write:

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
33

Just like

3
26,
3
27 lets us:

  • avoid mutating an array inside a
    3
    40 or
    3
    39 loop
  • assign its result directly to a new variable, rather than push into an array we defined elsewhere

Gotchas

The callback you pass to 

3
26 has to include a return statement if you want it to function properly. With 
3
27, you also have to include a return statement (unless you're using arrow functions), and you must make sure it returns a boolean value.

If you forget your return statement, your callback will return

3
53, which 
3
27 will unhelpfully coerce to
3
83. Instead of throwing an error, it will silently return an empty array! 

If you go the other route and return something that's isn't explicitly 

3
84 or
3
83, then 
3
27 will try to figure out what you meant by applying JavaScript's type coercion rules. More often than not, this is a bug. And, just like forgetting your return statement, it'll be a silent one. 

Always make sure your callbacks include an explicit return statement. And always make sure your callbacks in 

3
27 return
3
84 or
3
83. Your sanity will thank you.

Implementation

Once again, the best way to understand a piece of code is... well, to write it. Let's roll our own lightweight

3
27. The good folks at Mozilla have an industrial-strength polyfill for you to read, too.

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
35
2
  // return element for newArray, after executing something

9
3
let newArray = arr.map(callback(currentValue[, index[, array]]) {
39
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
  // return element for newArray, after executing something

9
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
let newArray = arr.map(callback(currentValue[, index[, array]]) {
43
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
45
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
let newArray = arr.map(callback(currentValue[, index[, array]]) {
47
2
0
let newArray = arr.map(callback(currentValue[, index[, array]]) {
49
2
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
51
2
4
  // return element for newArray, after executing something

9
2
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
55
2
8
  // return element for newArray, after executing something

9
  // return element for newArray, after executing something

0
const tasks = [
3

The Reduce Method

The syntax for the

3
28 array method in JavaScript is:

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
61
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
63
3
let newArray = arr.map(callback(currentValue[, index[, array]]) {
65

3
26 creates a new array by transforming every element in an array individually.
3
27 creates a new array by removing elements that don't belong. 
3
28, on the other hand, takes all of the elements in an array and reduces them into a single value.

Just like

3
26 and 
3
27, 
3
28 is defined on 
3
30 and so is available on any array, and you pass a callback as its first argument. But it also takes a second argument: the value to start combining all your array elements into. 

3
28 passes your callback four arguments:

  1. the current value
  2. the previous value 
  3. the current index
  4. the array you called 
    3
    28 on

Notice that the callback gets a previous value on each iteration. On the first iteration, there is no previous value. This is why you have the option to pass 

3
28 an initial value: It acts as the "previous value" for the first iteration, when there otherwise wouldn't be one.

Finally, bear in mind that 

3
28 returns a single value, not an array containing a single item. This is more important than it might seem, and I'll come back to it in the examples.

328 in Practice

Let's say you want to find the sum of a list of numbers. Using a loop, it would look like this:

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
67
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
69
3
let newArray = arr.map(callback(currentValue[, index[, array]]) {
71
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
73
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
let newArray = arr.map(callback(currentValue[, index[, array]]) {
75
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
}[, thisArg]);
8
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
2
0
let newArray = arr.map(callback(currentValue[, index[, array]]) {
80

While this isn't a bad use case for 

3
40, 
3
28 still has the advantage of allowing us to avoid mutation. With
3
28, we would write:

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
82
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
84
3
let newArray = arr.map(callback(currentValue[, index[, array]]) {
86
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
88

First, we call 

3
28 on our list of numbers. We pass it a callback, which accepts the previous value and current value as arguments, and returns the result of adding them together. Since we passed 
}[, thisArg]);
08 as a second argument to 
3
28, it'll use that as the value of 
}[, thisArg]);
10 on the first iteration.

With arrow functions, we would write it like this:

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
90
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
92

If we take it step by step, it looks like this:

Iteration PreviousCurrentTotal10112123333646410510515

If you're not a fan of tables, run this snippet in the console:

1
let newArray = arr.map(callback(currentValue[, index[, array]]) {
94
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
96
3
let newArray = arr.map(callback(currentValue[, index[, array]]) {
98
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
2
00
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
2
02
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
2
04
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
let newArray = arr.map(callback(currentValue[, index[, array]]) {
86
2
0
  // return element for newArray, after executing something

9
2
2
2
10
2
4
  // return element for newArray, after executing something

9

To recap: 

3
28 iterates over all the elements of an array, combining them however you specify in your callback. On every iteration, your callback has access to the previous value, which is the total-so-far, or accumulated value; the current value; the current index; and the entire array, if you need them.

Let's turn back to our tasks example. We've gotten a list of task names from 

3
26, and a filtered list of tasks that took a long time with... well, 
3
27. 

What if we wanted to know the total amount of time we spent working today?

Using a 

3
40 loop, you'd write:

1
2
14
2
let newArray = arr.map(callback(currentValue[, index[, array]]) {
71
3
}[, thisArg]);
4
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
2
20
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
2
22
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
2
24
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
}[, thisArg]);
8
2
0
  // return element for newArray, after executing something

9
2
2
2
30
2
4
  // return element for newArray, after executing something

9
2
6
2
34

With 

3
28, that becomes:

1
2
36
2
2
38

That's almost all there is to it. Almost, because JavaScript provides us with one more little-known method, called 

}[, thisArg]);
16. In the examples above, 
3
28 started at the first item in the array, iterating from left to right:

1
2
40
2
2
42
3
2
44
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
}[, thisArg]);
8
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
2
48
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
2
50

}[, thisArg]);
16 does the same thing, but in the opposite direction:

1
2
40
2
2
54
3
2
44
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
}[, thisArg]);
8
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
  // return element for newArray, after executing something

9
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
2
62

I use 

3
28 every day, but I've never needed 
}[, thisArg]);
16. I reckon you probably won't, either. But in the event you ever do, now you know it's there.

Gotchas

The three big gotchas with 

3
28 are:

  1. forgetting to 
    3
    46
  2. forgetting an initial value
  3. expecting an array when
    3
    28 returns a single value

Fortunately, the first two are easy to avoid. Deciding what your initial value should be depends on what you're doing, but you'll get the hang of it quickly.

The last one might seem a bit strange. If 

3
28 only ever returns a single value, why would you expect an array?

There are a few good reasons for that. First,

3
28 always returns a single value, not always a single number. If you reduce an array of arrays, for instance, it will return a single array. If you're in the habit of reducing arrays, it would be fair to expect that an array containing a single item wouldn't be a special case.

Second, if 

3
28 did return an array with a single value, it would naturally play nice with 
3
26 and 
3
27, and other functions on arrays that you're likely to be using with it. 

Implementation

Time for our last look under the hood. As usual, Mozilla has a bulletproof polyfill for reduce if you want to check it out.

1
2
64
2
2
66
3
2
68
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
2
70
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
2
72
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
51
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
2
68
2
0
2
78
2
2
const tasks = [
3

Two things to note here:

  1. This time, I used the name 
    }[, thisArg]);
    
    29 instead of 
    }[, thisArg]);
    
    10. This is what you'll usually see in the wild.
  2. I assign
    }[, thisArg]);
    
    29 an initial value if a user provides one, and default to
    }[, thisArg]);
    
    08 if not. This is how the real 
    3
    28 behaves, as well.

Putting It Together: Map, Filter, Reduce, and Chainability

At this point, you might not be that impressed. Fair enough: 

3
26,
3
27, and
3
28, on their own, aren't awfully interesting. After all, their true power lies in their chainability. 

Let's say I want to do the following:

  1. Collect two days' worth of tasks.
  2. Convert the task durations to hours instead of minutes.
  3. Filter out everything that took two hours or more.
  4. Sum it all up.
  5. Multiply the result by a per-hour rate for billing.
  6. Output a formatted dollar amount.

First, let's define our tasks for Monday and Tuesday:

1
2
82
2
2
84
3
2
86
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
2
88
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
2
90
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
2
84
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
2
94
2
0
2
96
2
2
2
98
2
4
  // return element for newArray, after executing something

00
2
6
  // return element for newArray, after executing something

9
2
8
  // return element for newArray, after executing something

04
  // return element for newArray, after executing something

0
2
84
  // return element for newArray, after executing something

2
  // return element for newArray, after executing something

08
  // return element for newArray, after executing something

4
  // return element for newArray, after executing something

10
  // return element for newArray, after executing something

11
2
90
  // return element for newArray, after executing something

13
2
84
  // return element for newArray, after executing something

15
  // return element for newArray, after executing something

16
  // return element for newArray, after executing something

17
2
88
  // return element for newArray, after executing something

19
2
90
  // return element for newArray, after executing something

21
2
84
  // return element for newArray, after executing something

23
  // return element for newArray, after executing something

24
  // return element for newArray, after executing something

25
  // return element for newArray, after executing something

26
  // return element for newArray, after executing something

27
2
98
  // return element for newArray, after executing something

29
  // return element for newArray, after executing something

00
  // return element for newArray, after executing something

31
  // return element for newArray, after executing something

32
  // return element for newArray, after executing something

33
  // return element for newArray, after executing something

34

And now, our lovely-looking transformation:

1
  // return element for newArray, after executing something

36
2
  // return element for newArray, after executing something

38
3
  // return element for newArray, after executing something

40
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
  // return element for newArray, after executing something

42
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
  // return element for newArray, after executing something

44
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
  // return element for newArray, after executing something

46
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
  // return element for newArray, after executing something

48
2
0
  // return element for newArray, after executing something

50
2
2
  // return element for newArray, after executing something

52
2
4
  // return element for newArray, after executing something

54
2
6
  // return element for newArray, after executing something

56
2
8
  // return element for newArray, after executing something

58
  // return element for newArray, after executing something

0
  // return element for newArray, after executing something

60
  // return element for newArray, after executing something

2
  // return element for newArray, after executing something

62
  // return element for newArray, after executing something

4
  // return element for newArray, after executing something

64
  // return element for newArray, after executing something

11
  // return element for newArray, after executing something

66

If you've made it this far, this should be pretty straightforward. There are two bits of weirdness to explain, though. 

First, on line 10, I have to write:

1
  // return element for newArray, after executing something

68
2
  // return element for newArray, after executing something

70
3
  // return element for newArray, after executing something

72
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
  // return element for newArray, after executing something

74

Two things to explain here:

  1. The plus signs in front of 
    }[, thisArg]);
    
    29 and 
    }[, thisArg]);
    
    38 coerce their values to numbers. If you don't do this, the return value will be the rather useless string, 
    }[, thisArg]);
    
    39.
  2. If you don't wrap that sum in brackets, 
    3
    28 will spit out a single value, not an array. That would end up throwing a 
    }[, thisArg]);
    
    41, because you can only use 
    3
    26 on an array! 

The second bit that might make you a bit uncomfortable is the last

3
28, namely:

1
  // return element for newArray, after executing something

68
2
  // return element for newArray, after executing something

78
3
  // return element for newArray, after executing something

80
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
  // return element for newArray, after executing something

82
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
  // return element for newArray, after executing something

84
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
}[, thisArg]);
8

That call to 

3
26 returns an array containing a single value. Here, we call 
3
28 to pull out that value.

Finally, let's see how our friend the 

3
40 loop would get it done:

1
  // return element for newArray, after executing something

88
2
  // return element for newArray, after executing something

90
3
  // return element for newArray, after executing something

92
let newArray = arr.map(callback(currentValue[, index[, array]]) {
2
  // return element for newArray, after executing something

94
let newArray = arr.map(callback(currentValue[, index[, array]]) {
4
2
48
let newArray = arr.map(callback(currentValue[, index[, array]]) {
6
  // return element for newArray, after executing something

98
let newArray = arr.map(callback(currentValue[, index[, array]]) {
8
3
00
2
0
let newArray = arr.map(callback(currentValue[, index[, array]]) {
71
2
2
3
04
2
4
3
06
2
6
let newArray = arr.map(callback(currentValue[, index[, array]]) {
19
2
8
}[, thisArg]);
8
  // return element for newArray, after executing something

0
2
48
  // return element for newArray, after executing something

2
3
14
  // return element for newArray, after executing something

4
3
16
  // return element for newArray, after executing something

11
}[, thisArg]);
8
  // return element for newArray, after executing something

13
  // return element for newArray, after executing something

15
  // return element for newArray, after executing something

17
  // return element for newArray, after executing something

19
3
23
  // return element for newArray, after executing something

21
  // return element for newArray, after executing something

9

Tolerable, but noisy.

Conclusion and Next Steps

In this tutorial, you've learned how 

3
26, 
3
27, and 
3
28 work; how to use them; and roughly how they're implemented. You've seen that they all allow you to avoid mutating state, which using 
3
39 and 
3
40 loops requires, and you should now have a good idea of how to chain them all together. 

By now, I'm sure you're eager for practice and further reading. For a masterclass in functional programming in JavaScript, check out our online course.