There is only one case where this might be a concern: unintentional global variables.
Consider the following Express route:
app.post('/foo', function(req, res) {
var user = req.cookies.user;
token = generateToken(user);
someAsyncOperation(user, req.body, function(err, result) {
saveUser(token, result);
res.send(result);
});
});
Do you see the error? user
is scoped the the function, but token
is an implicit global variable that will be shared across all requests.
In this example, it's likely the hypothetical author meant to use a comma instead of a semicolon after the definition of user
(which would cause token
to be properly scoped). Unfortunately, his finger came down a centimeter northeast and created an easy-to-miss bug.
- Request A comes in.
user
is loaded from a cookie, and some kind of token generation function creates a token that should be unique to the user.
- An asynchronous operation is queued, and the callback function is bound to the scope of request A.
- The async operation takes some amount of time, so node goes idle.
- Request B comes in. It initializes a new
user
in its scope.
- The global
token
gets overwritten with request B's token.
- Another async operation is queued for B; node goes idle again.
- A's async operation completes.
- Uh-oh. The result of A's operation is saved using B's token, because that's what
token
was last set to.
- B's async operation completes and saves more data to B's token.
In this scenario, nothing is saved to A and two sets of data are saved to B. This could result in everything from strange inconsistencies that are nearly impossible to reproduce and debug all the way up to actual financial loss. (Did I just send B two orders on accident?)
The good news is that it is easy to avoid this problem. Use strict mode. Strict mode makes assignment to implicit globals a ReferenceError
among other things. Just add to the top of your js files:
'use strict';
Or run node with the argument:
--use_strict
With strict mode on, you can't accidentally use an implicit global, so this is no longer a problem. Local variables and the req
/res
objects are safe; the only other area where you might run in to trouble is when you're intentionally using some kind of shared state, but the hazards there would be the same in any other language.