ES6 introduces the concept of block scope, which makes JS richer. Var const lets are different from ES6 const lets.

The difference between

  1. const letHas the effect of block scope,varThere is no
  2. varIt has the characteristics of variable promotion,const letDo not have
  3. Access before statement declarationconst letIn 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

  1. Compilation phase
  2. Execution phase

Compilation phase

During the compile phase, the code is divided into two parts

  1. Execution context
  2. 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:

  1. The test function is pushed and executed
  2. 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:

  1. a,b,d,fEnter theThe variable environmentdoVariable ascension
  2. {}Outside of thedFirst-in,Lexical environmenttheThe stack
  3. {}Within theeAfter 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:

  1. const letHas the effect of block scope,varThere is no
  2. varIt has the characteristics of variable promotion,const letDo not have
  3. inCompilation phase.varInto theThe variable environment, and theconst varInto theLexical environmentAnd maintain a similarThe stacktheLexical scope stack

Var const let, var const let, var const let