0

I have the following problem below:

My For Each

Write a function myForEach that accepts an array and a callback function. The behavior of myForEach should mirror the functionality of the native .forEach() array method as closely as possible.

Below is the code:

let sum = 0;

function addToSum(num) {
    sum += num;
}

let nums = [10, 20, 30];


function myForEach(anArray, callback){


  for (let i=0; i<anArray.length; i++){
    let num = anArray[i]; 
    //console.log(num)

    // I don't understand what this line of code is doing...
    callback(num, i, anArray); 
  }
  return undefined
}



myForEach(nums, addToSum);

console.log(sum); // 6

The above code works in this higher order function problem but I don't understand why. Specifically, what is the following line of code mean:

 callback(num, i, anArray); 

why are there 3 arguments? and where are these arguments getting passed to?

PineNuts0
  • 4,740
  • 21
  • 67
  • 112
  • 1
    `callback` is a reference to `addToSum`, which only uses the first argument `num` and ignores the next two passed. – Patrick Roberts Mar 30 '19 at 21:00
  • It's just to exactly mirror the native `forEach` method. The callback to that takes 3 arguments, the same as here: the element, its index, and the array itself: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach – Robin Zigmond Mar 30 '19 at 21:00
  • By the way, not sure if this is "cheating", but wouldn't it be much easier to just use `function myForEach (anArray, callback, thisArg) { anArray.forEach(callback, thisArg); }`? – Patrick Roberts Mar 30 '19 at 21:08

3 Answers3

1

"as closely as possible" is quite a harsh requirement. Javascript built-in functions are very complicated! These are the steps that the standard requires you to implement:

http://www.ecma-international.org/ecma-262/7.0/#sec-array.prototype.foreach

In layman's terms, since JS is a highly dynamic language, when you design a built-in function, you cannot just rely on parameters being what you expect them to be. In case of forEach:

  • the argument can be not an array, and even not an object
  • it might not have length or its length might be not a number
  • the callback might be missing or be not a function

and so on. That's why an "as close as possible" implementation should do lots of safety checks before it actually starts looping and calling.

You can find an example of a real-world forEach polyfill on the MDN page (only look if you decided to give up on this):

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

georg
  • 211,518
  • 52
  • 313
  • 390
0

Read here about it. Javascript doesn't care how many parameters you pass. For example, the following code still works but alerts undefined in the addToSum function:

let sum = 0;

function addToSum(num, i, k, j) {
  sum += num;
  console.log("i is:" + i);
  console.log("k is:" + k);
  console.log("j is:" + j);
}

let nums = [10, 20, 30];

function myForEach(anArray, callback) {
  for (let i = 0; i < anArray.length; i++) {
    let num = anArray[i];
    //console.log(num)

    // I don't understand what this line of code is doing...
    callback(num);
  }
  return undefined
}

myForEach(nums, addToSum);
console.log(sum);

So the thing that happens in your original code is that i and anArray that you pass does not effect the addToSum function at all, and the only parameter this function need is num so everything works good.

Omri Attiya
  • 3,917
  • 3
  • 19
  • 35
0

It's a callback function:

callback(); 

This is the function you passed into myForEach - in your code, it's addToSum, but it's a reference with a different name. It's used in case you have different functions for handling different things. In your code you can just as easily use addToSum and forget about callback altogether:

let sum = 0;

function addToSum(num) {
  sum += num;
}

let nums = [10, 20, 30];


function myForEach(anArray) {


  for (let i = 0; i < anArray.length; i++) {
    let num = anArray[i];
    //console.log(num)

    // I don't understand what this line of code is doing...
    addToSum(num, i, anArray);
  }
  return undefined
}



myForEach(nums, addToSum);

console.log(sum); 
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79