-5

At this moment I am having trouble understanding the difference between passing along an array-element - which is the case in the forEach method - because it passes every array-element along to the console.log and logs it onto the console, but it RETURNS undefined.

However, in the case of array.map, which passes along the array-element to the console.log too, but also returns every array-element back to the variable which it is connected to, and creates a new array.

I don't understand the difference between returning a value (array.map) and passing a value along to a function (array.forEach).

const fruits = ['mango', 'papaya', 'pineapple', 'apple']
const yummyFruits = fruits.forEach(fruit => {
  console.log(fruit);
  return fruit;
});

const numbers = [1, 2, 3, 4, 5]; 
const coolNumbers = numbers.map(number => {
  console.log(number);
  return number;
});

console.log(yummyFruits);
console.log(coolNumbers);

Edit

My question is not solved by the proposed duplicate.

halfer
  • 19,824
  • 17
  • 99
  • 186
Luka Momcilovic
  • 159
  • 2
  • 16
  • Possible duplicate of [JavaScript: Difference between .forEach() and .map()](https://stackoverflow.com/questions/34426458/javascript-difference-between-foreach-and-map) – Ludovit Mydla May 04 '19 at 20:21
  • I don't really care about the two methods, I care about the difference between returning a value and passing a value along to a function. – Luka Momcilovic May 04 '19 at 20:22
  • 1
    Your question doesn't make sense. The difference between a function that returns undefined and one that returns something else is *just* what they return. – Quentin May 04 '19 at 20:26
  • But like...the array.forEach method heads over to the array and grabs an element, then it RETURNS that element to the function? right? or am I thinking about this the wrong way? – Luka Momcilovic May 04 '19 at 20:27
  • in `forEach` method, returning anything doesn't make sense. It wouldn't be used anywhere. you'll just execut what needs to be done – Ludovit Mydla May 04 '19 at 20:29
  • @LukaMomcilovic — No. It calls the callback function with some arguments. So does map. The difference is what the functions returns. – Quentin May 04 '19 at 20:30
  • @Quentin ugh? okay, tell me where I'm wrong now. forEach heads over to the array and grabs an element. It passes it along to the function, right? Then, forEach returns undefined? but what do you call that which forEach does if not returning a value? – Luka Momcilovic May 04 '19 at 20:31
  • "calling a function' – Quentin May 04 '19 at 20:33
  • I guess, but ok, let's imagine array.forEach is a person. forEach heads over to the array and grabs an element, then what happens? – Luka Momcilovic May 04 '19 at 20:34
  • does nobody know? @Quentin – Luka Momcilovic May 04 '19 at 20:37
  • Then it calls the callback function. Then it does it again for the next value. And so on. – Quentin May 04 '19 at 20:38
  • This makes no sense at all @Quentin – Luka Momcilovic May 04 '19 at 20:39
  • I think your use of the word "return" may be confusing you (and some of us). Think of "return" as a way to get a value back from a function or method after it is finished running. `Array.map()` returns a new array after it makes some changes. Some functions are not designed to return a useful value (instead they may mutate an object, or simply provide a utility for working with the object(s) that are passed as arguments). `Array.forEach()` provides a simple utility that loops over the array so that you can either mutate the array, create some new object from the values of the array, etc. – benvc May 04 '19 at 20:40
  • @benvc I'm not trying to insult anybody, I'm just stating that - for me - none of this makes any sense. I'm sorry if I came off as rude. I'm just saying that, this makes no sense to me. hehe – Luka Momcilovic May 04 '19 at 20:48
  • Read [Functions reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions) and [Functions guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions). The second paragraph of the "Description" section in the functions reference explains a bit about return values. – benvc May 04 '19 at 20:50
  • so it's not actually the forEach method that is returning something, it's the callback function? ugh? – Luka Momcilovic May 04 '19 at 20:50
  • I do understand functions returning a value, I just don't understand what in the mighty gods forEach is doing? it's grabbing an array-element and then handing it over to the callback function. then what? – Luka Momcilovic May 04 '19 at 20:51
  • All Array.forEach does is to iterate over an array and apply a callback function to every element. All Array.map does is to iterate over an array, apply a callback function to every element, and return a new array containing values returned from each callback invocation. Map describes a transformation of one array into another one. – mrJoe May 04 '19 at 21:32
  • Thanks for editing a response to the proposed duplicate. It may be helpful to expand that edit to say _why_ you think it is different - merely stating that it does not apply cannot in itself affect whether that statement is true or false. – halfer May 04 '19 at 21:38
  • Could question be refined, because asking for a difference between return and passing is as asking for a difference between output and input. Then helpful answer can be found that clear any confusions among inner parameters and returns and outer arguments and return. –  May 13 '19 at 11:48

3 Answers3

1

Let's start with a bit of theory about functions.

All functions have 2 fundamental aspects:

  • they can return a value, to be used by the calling code

  • they can "do something" in the course of being executed, where "something" can mean executing arbitrary code (eg logging to the console, changing the DOM, sending network requests, updating local or global state - the possibilities are endless). Such effects, things which a function does which are unrelated to what - if anything - the function returns, are called "side effects".

Note that these 2 aspects of functions are completely independent of each other. A function could return a value while having no side effects at all (this is sometimes called a "pure" function), or it could perform some side effects while not returning anything - or it could do both. All 3 are regularly seen in Javascript code.

Now let's look at forEach and map in this light. Both are array methods, which take a function as an argument, and apply that function to each element of the array. Note that, if that function has any side effects, those will all be performed in both cases - because side effects are things that a function does simply by being executed. But forEach and map behave very differently in terms of any return values produced by the function passed to the method:

  • map builds a new array, made from the successive return values of the argument function when applied to each element of the original array. And it returns this new array.
  • but forEach completely ignores any return value of the argument function. Because of this, there is no need for it to return anything. (And it doesn't.)

In other words, forEach is for applying a function to every element of an array, where that function is only relevant due to its side effects. Whereas map is for functions that return something, and building a new array by taking the collection of function results. It's most often used with pure functions - although there's no rule against using it with a function with side effects. But if you're mainly concerned with the side effects, then forEach is usually more natural.

Note that map could be implemented in terms of forEach very easily - by initialising an empty array, and using forEach with a function that applies its function argument to each element of the source array and pushes it onto the new one (and then returning that new array at the end).

But in general, forEach is for using side effects, and map is for building a new array by applying a pure function to each element.

Robin Zigmond
  • 17,805
  • 2
  • 23
  • 34
  • The answer missed the third fundamental aspect of a function that is parameter passing, that also the question is about: "the difference between returning a value (array.map) and passing a value along to a function (array.forEach)" –  May 13 '19 at 11:53
1

There are several ways to iterate over the elements in an array, each with a different purpose.

For example forEach when you want to do something with every element in the array. It iterates over the array, but doesn't change it.

let myArray = [ 'A', 'B', 'B' ];

myArray.forEach( value => console.log(value) );

console.log(myArray); // Nothing changed: [ 'A', 'B', 'B' ]

Before forEach was added to Javascript, you could do the same thing like this:

var myArray = [ 'A', 'B', 'B' ];

var i;
for( i = 0 ; i < myArray.length ; i+=1 ) {
  console.log( myArray[ i ] );
}

With the new for of-statement the same thing can be done like this:

var myArray = [ 'A', 'B', 'B' ];

for( const value of myArray ) {
  console.log( value );
}

Sometimes you want to return a new array based on the values of the first array: You want to map the values. This returns a new array, based on the first.

let myTable = [ 'Alpha', 'Bravo', 'Charlie' ]
let myArray = [ 2, 1, 0 ]

let myNewArray = myArray.map( value => myTable[value] );

console.log(myNewArray); // [ 'Charlie', 'Bravo', Alpha' ]

Before map was added to Javascript you could do the same thing like this:

var myTable = [ 'Alpha', 'Bravo', 'Charlie' ]
var myArray = [ 2, 1, 0 ]

var myNewArray = [];
var i;
for ( i = 0; i < myArray.length; i += 1 ) {
  myNewArray[ i ] = myTable[ myArray[ i ] ];
}

console.log(myNewArray); // [ 'Charlie', 'Bravo', Alpha' ]

Sometimes you want to filter the values, only keeping some of the values.

let myArray = [ 6, 9, 10, 3, 15, 8, 2 ];

let myNewArray = myArray.filter( value => value >= 10 );

console.log( myNewArray ); // [ 10, 15 ]

Sometimes you wan to aggregate the content of the array, for example to sum all values:

let myArray = [ 6, 9, 10, 3, 15, 8, 2 ];

let sum = myArray.reduce(
 (sum, value) => sum + value, // the function
 0 // the start value
)

console.log( sum ); // 53

There is also find that will iterate over all values if the return value is false. The purpose of this is to find a value in the array.

const myArray = [ 6, 9, 10, 3, 15, 8, 2 ];

const myValue = myArray.find( value => value > 10 );

console.log( myValue ); // 15

And then there is some that iterates over the array until the function returns true. The purpose is to inspect the array to see if at least one value matches. If a match is found it stops the iteration.

const myArray = [ 6, 9, 10, 3, 15, 8, 2 ];

let myResult = myArray.some(
  (value, index) => {
    console.log('Inspecting index %d with value %d', index, value);
    return value >= 10
  }
);

console.log( myResult ); // true

And there is every that only returns true if all values matches the function.

const myArray = [ 6, 9, 10, 3, 15, 8, 2, 0 ];

let myResult = myArray.every(
  (value, index) => {
    const result = value > 0;
    console.log('Inspecting index %d with value %d: %s', index, value, result);
    return result;
  }
);

console.log( myResult ); // false

In all cases, every element is passed to the function, and you can do whatever you want. But it is bad practices to manipulate the original content of the array with find or map, or to use them if you don't want a new array. If you just want to process the values in the array, you use forEach.

some
  • 48,070
  • 14
  • 77
  • 93
  • Would also be great to explain how parameter passing and returns work as it is asked –  May 16 '19 at 19:11
0

When you call forEach on array, it makes whatever you want to do do with each element of array you pass, and returns undefined by definition.

map will do whatever you want with each element of array you pass (the same as forEach), but will create new array from values returned by inner function.

You will pass the same thing, the difference is only in what is the returned value (undefined vs. new array made up from what inner function returns)

Ludovit Mydla
  • 802
  • 9
  • 17