In JavaScript, when using a function expression (e.g. var myFunc = function() {...}), like any other variable declaration, you have to define the variable before using it. For example, the following example will not work (will result in Uncaught TypeError: myFunc is not a function):
var myVar = myFunc();
var myFunc = function() {
// code here...
}
However, in my routes/index.js file of a node js project, I have the following code (abbreviated obviously):
var router = express.Router();
.
.
.
router.post('/', function(req, res) {
...
...
var myVar = myFunc(); // WORKS!
...
...
}
var myFunc = function() {
...
}
The myFunc variable is declared after it is used, so shouldn't this throw an error?
There are two aspects to this:
Why can the callback passed to
router.postaccess themyFuncvariable, when the variable declaration is below it in the code?Why can the callback passed to
router.postaccess the function assigned to themyFuncvariable, when it's not assigned to the variable until below it in the code?First we'll deal with the variable, then we'll deal with its value (the function we assign to it):
It would if
varweren't hoisted. Butvaris hoisted. So when your module is loaded, first the JavaScript engine looks through it to find all variable declarations and function declarations, processes those, and then does the step-by-step code in your module.E.g., to the JavaScript engine, your module actually looks like this:
More on this on my anemic little blog: Poor misunderstood
varIt does. The only reason you're not running into trouble is that
myFuncisn't used until the callback you're passing intorouter.postis called, which is after the top-level scope code of your module script has been run (including the expression creatingmyFunc).E.g., what happens is:
The prep stuff (creating the vars
routerandmyFuncand setting them toundefined)The
express.Routercall, which assigns a new value torouterThe call to
router.post, passing in but not calling a callback functionCreation of the function, which assigns a new value to
myFuncLater, when a request comes in, the callback is called, by which time
myFunchas been created (and is accessible because the callback is a closure over the context wheremyFuncis declared)This is analogous to this:
First
setTimeoutis called, then the function is created and assigned tomyFunc, then later the callback function is called and calls the function viamyFunc.