Stack Overflow 421
Stack Overflow 421

Reputation: 95

How does a function gets passed in to another function?

I have a forEach function defined to do "something" with all the items in an array:

function forEach(array, action) {
  for (var i = 0; i < array.length; i++)
  action(array[i]);
} 

var numbers = [1, 2, 3, 4, 5], sum = 0;

So I could do:

forEach(numbers, console.log);

And it would print out all the numbers because 'console.log(array[i])' prints the number to the console. I get that part.

Here's where I'm stuck: If I pass the function below into the place of the action parameter, instead of 'console.log' then at what point does the function know about every element?

forEach(numbers, function(number) {
  sum += number;
});

console.log(sum);
// 15

How does it get evaluated? If I pass console.log into the last problem and it still has to be evaluated as 'console.log(array[i])' with the '(array[i])' code next to whatever parameter is being passed in, then doesn't that get applied to the entire function too since that function is the parameter? Such as below:

function(number) { sum += number; }(array[i])

Upvotes: 0

Views: 125

Answers (4)

Morieskie
Morieskie

Reputation: 405

Heres the solution to your problems:

    function forEach(array, action) {
        for (var i = 0; i < array.length; i++){
            if(typeof action == 'function'){
                action(array[i]);
            }else{
                var slices = action.match(/(.+)\.([a-zA-Z0-9]+)/);
                var object = eval(slices[1]);
                var action = slices[2];
                object[action](array[i]);
            }
        }
    }

I've tested it with both scenarios and it works like magic

enter image description here

enter image description here

Upvotes: 0

Bergi
Bergi

Reputation: 664930

How does it get evaluated?

It creates a new scope (with array, action and i variables) and assigns the function to the action variable - that's a function invocation.

Your

var sum = 0;
forEach([1, 2, 3, 4, 5], function(number) {
  sum += number;
});

is just the same as

var sum = 0;
{ // let's assume block scope here
  var array = [1, 2, 3, 4, 5],
      action = function(number) {
        sum += number;
      },
      i;
  for (i = 0; i < array.length; i++)
    action(array[i]);
}

If I pass console.log into the last problem and it still has to be evaluated, then doesn't that apply to the entire function too since that function is the parameter?

Yes, exactly. You are passing a function object - and whether get that by referencing the console.log variable or by creating it on the fly (with the function expression) doesn't matter to forEach. It only will get executed with action(…) - where the array[i] value is passed for the number parameter of your function.

Upvotes: 1

gen_Eric
gen_Eric

Reputation: 227280

In JavaScript, functions are first-class citizens. That means they can be treated as variables, just like strings, numbers, etc.

When you do:

forEach(numbers, function(number) {
  sum += number;
});

You are passing forEach an anonymous function. Instead of the function being in a variable, it's created on-the-fly. Inside your forEach function, action will contain your anonymous function.

In for for loop, the action function is called for each element.

Upvotes: 0

Quentin
Quentin

Reputation: 943939

at what point does the function know about every element

At no point (just like when you pass in console.log).

The forEach function calls it on this line:

action(array[i]);

At which point, it only knows about a single value from the array because that is all that is passed into it.

(It also knows about the sum variable because that is defined in a wider scope than the function).

Upvotes: 1

Related Questions