UPDATE to address comment:
May be my question was not clear enough. Let me rephrase it at the other way. If the Calculate has 5 arguments: function calculate(p1, p2, p3, p4, calculator) { return calculator(p1, p2); } Will it be possible to be called like: var result = calculate(2, 3, 9, 5, function (p4, p3) { return p3 - p4; }); //4 not -1 My actual question is: how can the one of parameters uses other parameters as its arguments and distinguish which parameter should become which argument?
The reason that the anonymous function knows to use the p1 and p2 arguments is because the parameters from the calculate function definition are what is passed into the anonymous function as arguments in the body of calculate.
Perhaps a clearer way to understand what is happening here is to change the name of the parameters in the function definition of the anonymous function so that those same parameter names aren't used in the function definition of your anonymous function. This creates a lot of confusion and is often done purposely in Computer Science textbooks when teaching about principles of programming languages and abstractions.
In addition to changing the parameter names in the anonymous function, changing the calculate parameter "calculator" to the parameter name "fn" may also help avoid confusion between calculate and calculator. Consider your function:
Function Definition:
function calculate(p1, p2, p3, p4, fn) {
// here you can see that calculate's p1 and p2 arguments (above) are bound
// to whatever function we pass into the fn parameter.
// Whatever values p1 and p2 represent are passed into the function "fn"
// and are assigned to the parameters p1 and p2 of fn.
return fn(p1, p2);
}
Function call calculate, with anonymous function:
How do we know which of the first 4 arguments get passed into the anonymous function vs which arguments aren't used?
// so here, we pass in an anonymous function that takes 2 parameters, one
//and two. We know from the definition above that whatever values are
// passed in as calculate's p1 and p2 parameters are passed into fn,
//so one and two are assigned the values 2 and 3 respectively,
// since p1 and p2 were assigned 2 and 3, and p1 and p2 were passed into
// fn in calculate's function definition above.
calculate(2, 3, 9, 5, function(one, two) {
return two - one;
});
// We know the values assigned to p1 and p2 are passed into the fn function
// as the parameters of the anonymous function known as one and two.
var result = calculate(2, 3, 9, 5, function(2, 3) {
return 3 - 2;
}
See return fn(p1, p2);
in the function definition for calculate, at the top of this answer, as a reminder of why the values assigned to p1 and p2 are passed into the anonymous function.
Thus, the anonymous function returns 3 - 2 = 1.
For further reading on how this concept can create abstractions, see Joel Spolsky's article - Can Your Programming Language Do This? Joel does a great job of explaining why JavaScript is so awesome!