In a comment on another thread I started, someone said this:
@adlwalrus yes. try this: var foo = function bar(){}; console.log(foo); But be aware that bar is only function name (what does it mean I’m not sure exactly myself) and not a reference to it, so you can’t call it by doing bar(). And assigning (even named function) is not the same as declaring a function. Hoisting (bumping to top of the scope) only works for declarations, assignment will stay in place. – valentinas 6 hours ago
What purpose does a function name serve if you can’t call it with bar()?
There are two ways to create a function in JavaScript, a “function declaration” and a “function expression.” I believe it was Doug Crockford who explained it best when he pointed out that unless “function” is the very first set of characters on a given line, you’re performing a function expression (not a declaration).
Function declarations are finicky creatures. You’ll recognize them when you see them. They look like this:
They’re always given a name (it’s requited) and the name is locally scoped to the lexical context under which the function is declared. So if you perform a function declaration in the global context, then the function can be referenced via it’s name globally. If you do it within a function, the function’s name can be referenced only within that function and any functions declared within that function.
I think the most important aspect of this method of declaring a function (one that is rarely commented on) is that the function initialization gets hoisted to the top of the current lexical context. Therefore, you should never, ever use a function declaration within a conditional, such as this:
A function expression is slightly different. Often, they’re directly assigned to a variable, like so:
This is nearly identical to the function declaration above except that the initialization is not hoisted. So you can do the following:
So, back to the original question. Function expressions can also have a name, though it’s not required and it’s not scoped to the context in which the function is declared (as with function declarations). Instead, it gets scoped to the function’s own lexical context. This is very useful in some cases. My personal favorite is this pattern:
Because of the parenthesis before the word “function”, this is a function expression and the name is scoped internally only. But that’s okay, because we only need to call it internally (via
setTimeout()). The result is that the function will execute once immediately, then will re-execute every second or so after it’s finishes execution. This is safer than usingsetInterval()because it will wait until it’s done executing before rescheduling itself, preventing overlaps that could cause missed executions and/or “domination” of the JavaScript thread.Essentially, the use of a named function expression is limited, but when you need it, it’s very powerful.