1. Scope chain 1.1. What is a scope
Talking about the scope chain, we have to start from the scope. Because the so-called scope chain is made up of multiple scopes. So, what is a scope?
1.1.1 Scope is the execution environment of a function during the execution period.
Each function has its own execution environment when executed, and the ECMAScript standard specifies that only functions in JavaScript have scopes. In other words, there is no block-level scope in JS. such as the following:
function Geta () { if (false) { var a = 1; } Console.log (a); Undefined}geta (); function Getb () { console.log (b);} Getb (); referenceerror:b is not defined
The above two-segment code differs in that: the Geta () function has a declaration of variable A, and the GETB () function does not have a declaration of variable B.
In addition, there is a point about the declaration in scope in advance.
1.1.2. declaration in scope in advance
In the Geta () function above, perhaps you still have doubts, why a= "undefined", the specific reason is because the declaration in the scope in advance: So the Geta () function and the following notation is equivalent:
function Geta () { var A; if(false) {a=1 }; Console.log (a);}
Now that you have mentioned the declaration of a variable in advance, you only need to figure out three questions:
1. What is a variable
2. What is a variable declaration
3. When the declaration is advanced.
What is a variable?
Variables include two types, common variables, and function variables.
- Common variables: all are common variables identified with Var . such as the following:
var x=1; var object={}; var Geta=function() {};
- Function variable: The function variable refers specifically to the following, fun is a function variable.
Function Fun () {};//This refers to a functional variable. Function variables are generally also stated as function declarations.
Like this, not a function declaration, but a function expression
var geta=function() {} //This is a functional expression var geta= function Fun () {};// This is also a function expression, and there is no function declaration. For more information on the differences between function declarations and function expressions, see the JavaScript Series---functions section two
What is a variable declaration?
Variables have common variables and function variables, so the declaration of a variable has a common variable declaration and a function variable declaration.
- General Variable Declaration
var x=1;//declaration + Assignment var object={}; Declaration + Assignment
This is always the case when the two variables above are executed.
var x = undefined; Declare var object == 1; = {}; Assign value
With respect to declarations and assignments, note that a declaration is completed before the first line of code in the function is executed, and the assignment starts at the time of the function execution. Therefore, the declaration always exists before the assignment. Moreover, the declaration period of a common variable is always equal to undefined.
- function Variable Declaration
A function variable declaration refers to the following:
function Geta () {}; function declaration
What time is the declaration advanced?
The declaration of all variables is completed when the first line of code inside the function starts executing. The order of-----declarations is shown in the 1.2 scope composition
1.2. The composition of the scope
The scope of the function, that is, the execution environment of the function, so all variables declared inside the function must be preserved within the scope of the function.
The variables used by a function in execution are not derived from the following three types:
1. The parameters of the function----from the scope inside the function
2. Variables declared inside a function (ordinary variables and function variables)----also originate from within the function scope
3. The variables from the outer scope of the function are placed in 1.3.
such as the following:
var x = 1; function Add (num) () { var y = 1; return x + num + y; X comes from an external scope, num originates from the parameter (the parameter also belongs to the internal scope), and Y is derived from the internal scope. }
So what is the scope of a function?
The scope of a function exists only when a function is called. At this point, when the function has not started executing, start creating the scope of the function:
Steps to create a function scope:
1. Declaration of a function parameter.
2. Declaration of function variables
3. Declaration of common variables.
4. The This pointer inside the function is assigned a value
...... The inner code of the function starts executing!
So, this explains why when a function is called, the Declaration is advanced, and the variables are declared when the function scope is created.
Here are a few things to emphasize about variable declarations.
1. The function parameter specifies the value of its formal parameter at the time of declaration.
function Add (num) { var num; Console.log (num); 1}add (1);
2. In the second step of the life of the function variable, the function variable overrides the previously declared declaration of the same name.
function Add (NUM1, fun2) { function fun2 () { var x = 2; } Console.log (typeof //functon fun2 () {var x=2;}} Add (functionfunction () { var x = 1});
3. In the third step, the declaration of the normal variable does not overwrite the previous parameter with the same name
function Add (fun,num) { var fun,num; Console.log (typeof//function console.log (num); //1} Add (function() {},1);
At the end of all declarations, the function starts executing code!!!
1.3. The composition of the scope chain
In JS, functions are allowed to be nested. That is, declaring another function inside a function
Similar to this:
function A () { var a=1; function B () { //within the A function, the function B is declared, which is called a nested function. var b=2;} }
For a, when a function is executed, the scope of its a function is created, then function B will refer to the scope of a when it is created, similar to the following
When function B executes, its scope resembles the following:
as you can see from the two images above, function B will refer to the scope of function a when it executes. Therefore, nesting like this function scope makes up the so-called function scope chain. When the variable is not found within its scope, it is progressively looked up along the scope chain, and an exception is thrown if the variable is still not found within the global scope.
2. Closures
First, realize that closures are meant to solve a problem. So, what is it that solves the problem?
Look at the following example:
var Funb,func; ( function () { var a = 1; function () { = a + 1; Console.log (a); } function () { = a + 1; Console.log (a); }} ()); Funb (); 2funC (); 3.
For Funb and func two functions, when running, it changes the value of variable A in function A, which pollutes the A variable.
The scope of the two functions at run time is as follows:
In this picture, variable a can be changed by function Funb and func, which is equivalent to the variables on the outer scope chain which are static variables for the internal scope, so it is easy to pollute the variables. There is also one of the most classic examples of closures:
var array = []; for (var i = 0; i < ten; i++) { varfunction () { console.log (i); } Array.push (fun);} var index = array.length; while (Index > 0) { array[-index] ();}//output is all ten;
The root cause of this similar problem is that it is not noticed that all variables on the outer scope chain are static.
Therefore, in order to solve the pollution problem of this variable and then introduce the closure!
How does it work? The idea is that, since the variables on the outer scope chain are static, copying the variables on the outer scope chain to the inner scope is not possible!! How to copy, of course, is through the function of the form of parameters ah.
Take the first example:
var Funb,func; ( function () { var a = 1; (function () { function () { = a + 1; Console.log (a); } } (a)); (function (a) { function () { = a + 1; Console.log (a); } } (a));} ()); Funb ()| | FunC (); The output is all 2 and there is no change in the value of a on the scope chain.
When the function executes, the structure of the memory:
The memory structure in the diagram shows that the introduction of closures is actually sacrificing performance, because the execution of anonymous functions extends the scope chain and copies a copy of the variable.
JavaScript series----scope chains and closures