0

I had started to learn JavaScript for web development and I am currently stuck at a point in the callback function. The problem is that I can't understand how arguments are passed in JavaScript.

CODE:

const arr = [1, 2, 3, 4, 5, 6, 7, 8];
function myfunc(value){ //i had set a parameter 'value'
  console.log(value); // i had printed the 'value'
}
arr.forEach(myfunc); // i had not passed any argument in myfunc

I am really confused about how myfunc (value) gets the 'value' parameter from in forEach function or any functions like:

const numbers1 = [45, 4, 9, 16, 25];
function myFunction(value) { //myFunction has parameter 'value'
  return value * 2;
}
const numbers2 = numbers1.map(myFunction); /* here, how value arguments are passed to 
myFunction? */
ADITYA RAJ
  • 123
  • 1
  • 2
  • 8
  • https://stackoverflow.com/questions/3458553/javascript-passing-parameters-to-a-callback-function – Dimitris Papageorgiou Dec 07 '21 at 18:35
  • Possible duplicate of [How a callback function in javascript receives it's arguments values](https://stackoverflow.com/questions/24751875/how-a-callback-function-in-javascript-receives-its-arguments-values) – Felix Kling Dec 07 '21 at 19:01

4 Answers4

7

They get passed in because forEach has some code which passes them in. forEach's implementation will look something like this:

forEach(callback) {
  // `this` is the array we're looping over
  for (let i = 0; i < this.length; i++) {
    callback(this[i], i, this);
  }
}

So forEach handles the logic of looping over the array, and then for every element in the array, it's going to call your function and pass in three parameters (the value, its index, and the entire array). You just write a function that uses those values in whatever way you need it to. If you don't need to use all 3 parameters, you can simply leave out any arguments to the right of the ones you need.

Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • You can't technically leave them out. Omitting, say, argument 2 yet wanting argument 3 won't work, as it treats your variable for argument for variable 3 as variable 2. You could use `_`, but Javascript treats that as an actual variable and not a placeholder. I usually name the 3 parameters as "i", "v", and "arr" (although I next to never use the latter argument) and don't use the ones I don't need. – Reality Dec 07 '21 at 19:09
  • 1
    Ok, I've reworded so the sentence can no longer be interpreted as implying that middle arguments can be omitted while still using later arguments. – Nicholas Tower Dec 07 '21 at 19:12
  • A tad bit wordy, but yeah that's nice. It was mainly just a note to anyone who sees your answer. – Reality Dec 07 '21 at 19:14
4

The functional extensions on the javascript Array require a function as an argument. That function can be:

  • A named function
function doSomething() {} // This is a named function
  • An anonymous function
// This is an anonymous function because we didnt give a name to it
[1,2,3].forEach(function (value) { console.log(value) })
  • A fat-arrow function (lambda expression).
// It's called fat arrow because well, the arrow is fat
[1,2,3].forEach((value) => console.log('hey', value))

The implementation for the functional extensions on Array always pass three arguments: the value, the index and the array the function is being applied to

The way function arguments work in JS is that if you pass more than the required arguments to a function JS will just drop the rest, and if you pass more than the ones needed those will have a value of undefined unless you have specified a default value for those

const array = [1,2,3]

// I am just getting the value and the name "value" could be any name
array.forEach((value) => console.log(value)) 
// here my fat-arrow function takes two parameters, since forEach passes three parameters we're good to go
array.forEach((value, index) => console.log(value, 'at', index))
// Here we're using all arguments without dropping any
array.forEach((value, index, array) => console.log(value, index, array)) 
// that is because  the forEach predicate only passes three arguments and hence the last is undefined
array.forEach((value, index, array, fourth) => console.log('here', fourth, 'is always undefined')) 
Some random IT boy
  • 7,569
  • 2
  • 21
  • 47
  • 1
    Pedantic nit: a "predicate" returns a bool. That's applicable to filter and find etc, but not forEach or reduce, etc. "function" is a better word for the general functional param (or "closure", as long as I'm being snooty). – danh Dec 07 '21 at 18:44
  • I agree and I will update the answer – Some random IT boy Dec 07 '21 at 18:45
  • Are the different ways to define a function relevant? If so, why didn't you include (object/class) methods? `forEach` doesn't care how the function object was created... – Felix Kling Dec 07 '21 at 18:57
  • I don't know if they are relevant but OP used named functions and anonymous functions and I decided to put some light in those zones when I answered but you'd be right I am missing objects / classes functions and methods – Some random IT boy Dec 07 '21 at 19:05
2

This makes sense to the OP, probably:

const numbers1 = [45, 4, 9, 16, 25];
numbers1.forEach(e => console.log(e));

So probably this will make sense, too:

const numbers1 = [45, 4, 9, 16, 25];
const someFunction = e => console.log(e);
numbers1.forEach(someFunction);

If so, then this will make sense, too:

function someFunction(e) {
  console.log(e));
}
numbers1.forEach(someFunction);
danh
  • 62,181
  • 10
  • 95
  • 136
1

With both arr.forEach(myfunc) and numbers1.map(myFunction), you are passing a reference to your function to the standard functions map and forEach. Both of these standard array functions then use your reference inside and call your function with always the same parameters.

So, e.g. for forEach, in each loop, your function is called like this myfunc(element, index, array). The parameters are defined by the forEach function. You can also define such a function inline as arr.forEach(function (element, index, array) {...} but it basically just does the same.

ssc-hrep3
  • 15,024
  • 7
  • 48
  • 87