Before we get to closures, we must know on the concept of scope in JavaScript.
In JavaScript, unlike many other languages, there is no curly braces scope, but there is function scope. A variable defined in a function is not visible outside the function, but a variable defined in a code block (an if or a for loop) is visible outside the block.
var a = 1; function f(){var b = 1; return a;} f(); 1 b b is not defined
The variable a is in the global space, whereas b is in the scope of the function f(). So,
If you define a function n() nested inside f(), n() will have access to variables in its own scope, plus the scope of its "parents". This is known as scope chain, and the chain can be as long (deep) as you need it to be.
var a = 1; function f() { var b = 1; function n() { var c = 3; } }
In JavaScript, functions create their environment (scope) when they are defined, not when they are executed. This known as lexical scope.
Let's see an example:
function f1() { var a = 1; f2(); } function f2() { return a; } f1(); a is not defined
Inside the function f1() we call the function f2(). At the time when f2() was defined (as opposed to executed), there was no a in sight. f2(), just like f1(), only has access to its own scope and the global scope. f1() and f2() don't share their local scopes and f2() will have no access to a.
When a function is defined, it "remembers" its environment, its scope chain. Also you can add, remove or update variables inside the scope of the function any time.
From the example above, declare a global variable a, f2() will see it, because f2() knows the path to the global environment and can access everything in that environment. Also notice how f1() includes a call to f2(), and it works- even though f2() is not yet defined.
function f1() { var a = 1; return f2(); } function f2() { return a; } f1(); a is not defined var a = 5; f1(); 5 a = 55; f1(); 55 delete a; true f1(); a is not defined
This behavior gives JavaScript great flexibility—you can add and remove variables and add them again. You can delete the function f2(), then redefine it again with a different body. f1() will still work, because all it needs to know is how to access its scope and not what this scope used to contain at any time.
Continuing with the example above:
delete f2; true f1() f2 is not defined var f2 = function() { return a * 2; } var a = 5; 5 f1(); 10