1

Following is the code in which I need some clarification. I was expecting this code to console 'mango', 'apple', 'orange' one by one similar to Option 2 but this is throwing another input which I am not getting how JavaScript is spitting this output.

const myFunc = (...data) => (data.map(console.log))

myFunc('mango', 'apple', 'orange')

Option 2 - (Expected Output)

var myFunc = (...data) => {
  data.map(x => {
    console.log(x)
  })
}

myFunc('mango', 'apple', 'orange')

Correct my understanding with this please, as I was thinking that data.map(console.log) will log the items only.

Nesh
  • 2,389
  • 7
  • 33
  • 54

4 Answers4

7

Your code works fine, and should produce the expected result for other functions.

Array#map accepts a callback function, which it will call for each element of the array. MDN:

The callback function accepts the following arguments:

currentValue
The current element being processed in the array.

indexOptional
The index of the current element being processed in the array.

arrayOptional
The array map was called upon.

Because you're passing console.log as the callback function, you're effectively writing this:

const myFunc = (...data) => (data.map((curVal,index,arr) => console.log(curVal,index,arr)))

myFunc('mango', 'apple', 'orange')

So the extra output is because you're also logging the index and array parameters unknowingly.

Just be aware that any other function you use will also receive these extra parameters. If they only accept one parameter, then it should work exactly as you expect.

Klaycon
  • 10,599
  • 18
  • 35
3

console.log takes more than one parameter.

You could wrap your function in another function and use only the first parameter.

forEach is better if the result of map is never used.

const single = fn => first => fn(first);

var myFunc = (...data) => {
    data.forEach(single(console.log));
}

myFunc('mango', 'apple', 'orange')
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Thanks a lot for sharing the best practices :) +1 – Nesh Jun 23 '20 at 21:04
  • A quick query, is it advisable to use spread operator to accept multiple parameters or we should avoid this approach ? – Nesh Jun 23 '20 at 21:07
  • @Nesh, it depends ... sorry. – Nina Scholz Jun 23 '20 at 21:08
  • 1
    @Nesh, when used in a parameter list it is a [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). This is a language feature and you should definitely use it if your goal is to accept a totally arbitrary number of parameters. If you know the number of parameters, they should be specified explicitly. – Klaycon Jun 23 '20 at 21:10
1

Here is what map does under the hood:

function map(a, f) {
  var b = new Array(a.length);
  for (let i = 0; i < a.length; i++) {
    b[i] = f(a[i], i, a);
  }
  return b;
}

console.log(
  map([0, 1, 2, 3], function(x, i, a) {
    return x * x;
  })
);

As you can see, f receives 3 parameters: the element a[i], its position i, and the array a. It's up to you to use them or not, as shown in these twisted examples:

console.log(
  ["a", "b", "c", "d"].map(function(x, i, a) {
    return x + " " + a[(i + 1) % a.length];
  })
);

console.log(
  ["a", "b", "c", "d"].map(function(_, i) {
    return "2^" + i + " = " + 2 ** i;
  })
);

Since console.log takes any number of parameters, if you pass it directly to map it will use all of the three parameters a[i], i and a. To pick only one parameter you need a filter:

"abcd".split("").map(function(x) {
  console.log(x);
});

However, as Nina said, forEach is more appropriate in this case since we ignore the output of map (which is [undefined × 4]):

"abcd".split("").forEach(function(x) {
  console.log(x);
});
0

The output in Option 1 will be :-

mango 0 (3) ["mango", "apple", "orange"]
apple 1 (3) ["mango", "apple", "orange"]
orange 2 (3) ["mango", "apple", "orange"]

This is because of below 2 reasons:-

The map() method creates a new array with the results of calling a function for every array element. The map() method calls the provided function once for each element in an array, in order.

SAURABH
  • 127
  • 7