scope
Before ES6, JavaScript had no block-level scope, only global scope and function scope
Scopes are layered, with inner scopes having access to variables in outer scopes and not vice versa
Var a=1 function aa(){var b=2 console.log(a)} console.log(b) Output 1 b Error undefinedCopy the code
Block statements (statements between braces {})
Such as if and switch conditional statements or for and while loop statements, unlike functions, they do not create a new scope
If (true) {// The 'if' conditional statement block does not create a new scope var name = 'Hammad'; // name is still in global scope} console.log(name); // logs 'Hammad'Copy the code
Block-level scoped let and const declarations
-
The declared variable cannot be accessed outside the scope of the specified block. Block-level scopes are created inside a function and inside a code block (wrapped by a pair of {})
-
No variable promotion
-
No duplicate declaration
-
Nifty use of bound block scope in loops
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a6; / / 10
In the above code, the variable I is declared by the var command and is valid globally, so there is only one variable I globally. The value of variable I changes each time through the loop, and the console.log(I) inside the function assigned to array A refers to the global I. That is, all the I’s in array A refer to the same I, causing the runtime to print the value of the last round of I, which is 10.
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); / / 6Copy the code
In the above code, the variable I is declared by let, and the current I is only valid for this loop, so each loop I is actually a new variable, so the final output is 6. You might ask, if the variable I for each cycle is redeclared, how does it know the value of the previous cycle and thus calculate the value of the current cycle? This is because the JavaScript engine internally remembers the value of the previous cycle, and when it initializes the variable I of this cycle, it evaluates on the basis of the previous cycle.
Another special feature of the for loop is that the part that sets the variables of the loop is a parent scope, while the inside of the loop body is a separate child scope.
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc
Copy the code
The above code works correctly, printing three ABCs. This indicates that the variable I inside the function and the loop variable I are not in the same scope and have separate scopes
The scope chain
What is a scope chain
Variables that are not currently defined in scope become free variables. How to get the value of the free variable – look for the field where the function was created. The value is in scope. The emphasis here is on “create”, not “call”. Look up layer by layer until you find the global scope and when you don’t find it, you give up. This layer by layer relationship is the scope chain
var a = 10
function fn() {
var b = 20
function bar() {
console.log(a + b) //30
}
return bar
}
var x = fn(),b = 200
x()
Copy the code
Fn () returns the function bar, which is assigned to x. By executing x(), the bar function code is executed.
When taking the value of b, fetch it directly from fn’s scope.
The value of a is 30, and the value of a is 30. The value of a is 30, and the value of a is 30
Scope and execution context
JavaScript execution is divided into two phases: explain and execute. The two phases do different things:
Explain the stage
- Lexical analysis
- Syntax analysis
- Scope rules are determined
Execution phase
- Create execution context
- Execute function code
- The garbage collection
The JavaScript interpretation phase determines the scope rule, so the scope is defined when the function is defined, not when the function is called, but the execution context is created before the function executes. The most obvious aspect of the execution context is that the reference to this is determined at execution time. The variables accessed by scope are determined by the structure of the code that was written.
The biggest difference is between scope and execution context
The execution context is determined at run time and can change at any time; The scope is defined at definition and does not change