JavaScript and Scope VI - Closures
June 10, 2019 • 1 min read
In JavaScript and Scope II we saw that function scope is not determined by where a function is run. Instead, it is determined by where a function is declared.
var i = 10;
function foo() {
var i = 2;
function bar() { i = i + 1;
console.log ('value of i when bar is declared inside foo: ', i);
}
bar();
}
foo(); // logs 3
But the example above doesn't fully illustrate lexical scope because the bar
function is also run inside the foo
function. Let's run the bar
function outside of the foo
function.
var i = 10;
function foo() {
var i = 2;
function bar() {
i = i + 1;
console.log ('value of i when bar is declared inside foo: ', i);
}
return bar;}
var barFunc = foo();
barFunc(); // Runs in global scope but logs 3
In the code above, we no longer run bar
inside of foo
. Instead we return the inner function without running it. Then we run the function on the last line of code: it runs in the global scope. Most importantly it runs after foo
is done running. But it does not use the global i
variable. Instead it uses the i
variable from the function that has already finished running!
The official name for what you just saw is closure. That's how simple closure is. All closure means is that even when a function is run outside of the scope it was declared in, it still uses the scope from where it was declared. In this case, inner function bar
uses the scope of outer function foo
. This is true even though foo
has stopped running by the time we run bar
.
This breaks our expectation that the scope of foo
no longer exists when it stops running.