ES6 introduces the concept of block scope, which makes JS richer. Var const lets are different from ES6 const lets.
The difference between
const
let
Has the effect of block scope,var
There is novar
It has the characteristics of variable promotion,const
let
Do not have- Access before statement declaration
const
let
In addition to the second point, declared variables report errors
Block scope
Before es6, there were only function scopes and global scopes. Except for these two scopes, variables declared by var inside {} were normally accessible from outside. After ES6, block scopes were introduced, which allowed {} to define const lets in {}. Variables defined by let const cannot be accessed externally as follows:
// var
function testVar(){
if(1) {
var b = 3;
}
console.log(b);
}
testVar(); / / 3
// let
function testLet(){
if(1) {
let b = 3;
}
console.log(b);
}
testLet(); // error: Uncaught ReferenceError: b is not defined
Copy the code
Variable ascension
In a scope, a variable declared with var can be accessed in advance, except that the value is undefined, while a const let will report an error.
// var
function testVar(){
console.log(b); // undefined
var b = 3;
}
testVar();
// let
function testLet(){
console.log(b); // Uncaught ReferenceError: Cannot access 'b' before initialization
let b = 3;
}
testLet();
Copy the code
Var declarations do something like this:
// Simulate variable promotion of var
function testVar(){
var b = undefined;
console.log(b);
b = 3;
}
testVar();
Copy the code
So it outputs normally
Those are all declared variables, so why is there such a difference? (Const lets are the same because they are just a declared variable and a declared constant.)
JS code execution process
Cause the reason of such difference, have to start from the execution process of a section of JS code!
// a piece of javascript code
test();
console.log(testVar);
function test(){
console.log('test function');
}
var testVar = 'testVar';
Copy the code
How does the above code work in the JavaScript engine? The JavaScript engine actually executes a piece of code in two stages
- Compilation phase
- Execution phase
Compilation phase
During the compile phase, the code is divided into two parts
- Execution context
- Executable code
In the execution context, there are two parts: one is the variable environment and the other is the lexical environment
The variable environment contains variable declarations and function declarations. This is actually how variable promotion works. The engine allocates memory for test and testVar. This is why the test function and testVar function worked well in the first place;
// Simulate the execution order of the compiled code. That's not the case
function test(){
console.log('test function');
}
var testVar = undefined;
test();
console.log(testVar);
testVar = 'testVar';
Copy the code
Execution phase
The execution phase is much simpler:
- The test function is pushed and executed
- TestVar assignment for
'testVar'
How is the block scope of a const let compiled?
// a string of let,const JS code
var a = 1;
var b = 2;
let c = 3;
{
var d = 4;
let e = 5;
var f = 6;
}
Copy the code
Execution process:
The lexical environment of the previous compilation phase is finally used
Here, variables declared by var, whether inside or outside {}, are promoted in the variable environment, while variables declared by let and const are maintained in the lexical environment like a stack structure
The specific process is as follows:
a,b,d,f
Enter theThe variable environmentdoVariable ascension
{}
Outside of thed
First-in,Lexical environmenttheThe stack
{}
Within thee
After theLexical environmenttheThe stack
At this point, the compile phase is complete
How does the execution phase access these variables
Access starts at the top of the stack in the lexical environment, works its way to the bottom of the stack, and finally returns to the variable environment for access
For example, the a = 1 assignment statement starts from the top of the lexical environment, continues to the bottom of the stack, and finally returns to the variable environment for access. Finally, a is assigned 1, while c = 3 is directly accessed from the lexical environment, and does not enter the variable environment
Morphology in the environment variable is, of course, are limited in the {}, each stack is corresponding a scope, such as c is the global scope, so only in the global context is access to, and e are in the scope inside the {}, can only be accessed in {}, {} the code after the execution, e lexical scope out a stack of the variable is destroyed, Just like the function in and out of the stack
conclusion
Const let differs from var mainly in:
const
let
Has the effect of block scope,var
There is novar
It has the characteristics of variable promotion,const
let
Do not have- inCompilation phase.
var
Into theThe variable environment, and theconst
var
Into theLexical environmentAnd maintain a similarThe stack
theLexical scope stack
Var const let, var const let, var const let