JavaScript does that automatically by creating closures.
- Every function creates its own scope.
- Scopes are nested, since functions can be defined within functions.
- Every new nested scope ("function") can see all the variables that were defined in any parent scope at the point of its (i.e that new function's) creation. This is called a closure.
- Every variable from any parent scope is "by reference" - child scopes ("functions") always see their current values.
- The point in time when the function runs does not matter, only the point in time when it was declared (see first example).
- The scope where a function runs in does not matter, only the scope a function was defined in (see second example).
Here
var myGlobalVariable = [];
// define function => creates closure #1
function myFunction() {
var notGlobalVariable = "somedata";
// define function => creates closure #2
var myOtherFunction = function() {
myGlobalVariable.push(notGlobalVariable);
}
// execute function
myOtherFunction();
}
myFunction(); // myGlobalVariable will be ["somedata"]
you create two scopes:
myFunction
can see myGlobalVariable
- the anonymous function stored in
myOtherFunction
can see myGlobalVariable
and notGlobalVariable
.
Now assume a small change:
var myGlobalVariable = [];
// define function => creates closure #1
function myFunction(callback) {
var notGlobalVariable = "somedata";
// define function => creates closure #2
var myOtherFunction = function() {
myGlobalVariable.push(callback());
}
// execute function
myOtherFunction();
}
// define function => creates closure #3
function foo() {
var thisIsPrivate = "really";
// define function => creates closure #4
return function () {
return thisIsPrivate;
}
}
myFunction(foo()); // myGlobalVariable will be ["really"]
You see that the callback
function has access to thisIsPrivate
because it was defined in the right scope, even though the scope it is executed in cannot see the variable.
Likewise the callback
function will not be able to see notGlobalVariable
, even though that variable is visible in the scope where the callback is executed.
Note that you always must use var
on any variable you define. Otherwise variables will be silently global which can and will lead to hard to fix bugs in your program.