tl;dr: Because many functions are actually not reused.
I think you answered your own question:
... instead of just the function name which can be reused?
Many of these are "one-off" cases. The line of code is executed once and the passed function doesn't have to be reused.
For example, if I want to bind an event handler to a body
and I don't intend to reuse the event handler anywhere, why should I write
function bodyEventHandler() {}
document.body.addEventListener('click', bodyEventHandler);
and unnecessarily pollute the current scope with bodyEventHandler
?
document.body.addEventListener('click', function() {...});
has the same effect, doesn't pollute the scope and keeps the function definition where it is used.
JavaScript is very much event-driven, and most event handlers are actually not going to be reused anywhere else.
Keeping the function definition where the function is used is also a common reason IMO. Some functions are either very simple, but it may not be easy to give them descriptive names.
E.g. if you are not familiar with the term "pluck", would you understand what
var names = users.map(pluck('name'));
really does? Maybe you can infer it from the other variables names.
However,
var names = users.map(function(user) { return user.name; });
makes it immediately clear.
In fact, you will see these even more often, now that ECMAScript 6 introduces arrow functions, which are like lambda functions in other languages:
var names = users.map(user => user.name);
I also think you have a misconception of what exactly happens under the hood when you pass a function:
... pass an entire function definition as an argument instead of just the function name ...
foo(bar)
does not pass the name "bar" to foo
. It passes the function object that is referenced by the variable bar
. That is no different from foo(function() { ... })
. The only difference is that we are not (temporarily) storing the function in a variable.