Put the variables in the higher level function back, and so on until the global object. When the function needs to query the value of a variable, JS interpreter will go to the scope of the chain to find, from the first local variables to find, if not found the corresponding variable, then to the next level of the chain to find, once the variable, is not continued. If you find the last variable you didn't find, the interpreter will return undefined.
Scope
There are two types of scopes in JavaScript: function scope and global scope.
The variables declared in a function and the parameters of the function have the same scope, that is, the function scope. An example of a simple function scope:
function foo () {
var bar = 1;
{
var bar = 2;
}
return bar; 2
}
Unlike other block-scoped languages such as C, this will always return 2.
Global scope, which can be understood as a Window object (Node.js is global) for browsers:
var bar = 1;
function foo () {}
alert (Window.bar); 1
alert (Window.foo); "Function foo () {}"
For the variable bar and function Foo are both global scopes and are a property of window.
Scope chain
When you access a variable in JavaScript, it starts with local variables and arguments, traversing the scope up and down through the scopes until the global scope.
var scope = 0, zero = "Global-scope";
(function () {
var scope = 1, one = "scope-1";
(function () {
var scope = 2, two = "scope-2";
(function () {
var scope = 3, three = "scope-3";
Scope-3 scope-2 scope-1 Global-scope
Console.log ([Three, two, one, Zero].join (""));
Console.log (scope); 3
})();
Console.log (typeof three); Undefined
Console.log (scope); 2
})();
Console.log (typeof two); Undefined
Console.log (scope); 1
})();
Console.log (typeof one); Undefined
Console.log (scope); 0
In the innermost function, each variable can be traversed and output. In the function of the penultimate layer, the variable three cannot be traversed to find, so the output is undefined.
For example of a popular point, you are prepared to spend money to buy something, will first touch their wallet, no you can find your father, your father did not find your grandfather, .... And when your dad doesn't have money to buy things, he doesn't come to you.
Closed Bag
In one function, define another function, called a function nesting. The nesting of functions will form a closure.
Closures and scope chains complement each other, and the nesting of functions forms a closure while creating multiple scopes of chain relationships.
function bind (func, target) {
return function () {
Func.apply (target, arguments);
};
}
So how do you know about closures?
External functions cannot access inline functions
External functions also cannot access parameters and variables of inline functions
Inline functions can access parameters and variables of external functions
To put it another way: inline functions contain the scope of external functions
Let's take a look at the example of the scope chain described earlier, this time from a closure perspective:
var scope = 0, zero = "Global-scope";
(function () {
var scope = 1, one = "scope-1";
(function () {
var scope = 2, two = "scope-2";
(function () {
var scope = 3, three = "scope-3";
Scope-3 scope-2 scope-1 Global-scope
Console.log ([Three, two, one, Zero].join (""));
Console.log (scope); 3
})();
Console.log (typeof three); Undefined
Console.log (scope); 2
})();
Console.log (typeof two); Undefined
Console.log (scope); 1
})();
Console.log (typeof one); Undefined
Console.log (scope); 0
The innermost function has access to all variables defined internally and externally. The second-lowest function cannot access the innermost variables, and at the same time, the innermost scope = 3 does not have an effect on the variable with the same name outside it.
Another angle to understand the closure:
Every time an external function is called, the inline function is created once
When it is created, the scope of the external function (including any local variables, parameters, and so on) becomes part of the internal state of each inline function object, even after the external function finishes executing and exiting
Look at the following example:
var i, list = [];
for (i = 0; i < 2; i + + 1) {
List.push (function () {
Console.log (i);
});
}
List.foreach (function (func) {
Func ();
});
We're going to get two times "2" instead of the expected "1" and "2", because the two functions in the list access the variable I are the same variable for the previous-layer scope.
We changed the code to take advantage of the closure to solve the problem:
var i, list = [];
for (i = 0; i < 2; i + + 1) {
List.push ((function (j) {
return function () {
Console.log (j);
};
}) (i));
}
List.foreach (function (func) {
Func ();
});
The outer "Execute function immediately" receives a parameter variable I, which exists as a parameter J within its function, pointing to the same reference as the name J in the returned inner-layer function. After the outer function executes and exits, the parameter J (at which time its value is the current value of i) becomes part of the state of the inner-layer function preserved.
Closed Bag
Understanding the scope chain is important for understanding the concept of closures. A closure is a function that has access to a variable in another function's scope. Generally in the form of internal functions. For example:
var counting= (function () {
var count=0;
function Autoplus () {
Console.log (count++);
}
return autoplus;
})();
Counting ();//0
Counting ();//1
Counting ();//2
Autoplus () is a closure. Each time the counting () is invoked, a value is returned. The child shoe that understands the scope chain, will feel that the closure can access the variable of its parent function is taken for granted! Because the variable object of its parent function is within its scope.
So where is the closure special? Is that even if it is returned and called elsewhere, it can still access the variables of its parent function. In general, when a function completes, the local active object (that is, the variable object) is destroyed. As in the example above, the anonymous function is executed It stands to reason that the count variable should be destroyed. But because of closures, the situation is different!
The reason is that the closure contains functions that are executed, and that the active object containing the function is not destroyed. In other words, the variable object referenced by the closure scope chain remains in memory. The active object containing the function is only actually destroyed when the closure is destroyed. So using closures can take up more memory than normal functions, so use them sparingly.