The way JavaScript works is that you parse the code, get all the declared variables or functions, and then run them. The result is that all declared variables or functions are promoted to the head of the code. This is called declaration prompt promotion.

Let’s start with a classic example of the same thing: This is an example where we all know that the variable is promoted; That’s undefined. The question is, where is this process of ascension sent? How did it happen?

console.log(a);  // undefined
var a = 1;
b()              // 1
function b() {
    console.log(a)
}
Copy the code

First, JavaScript execution process

1. JavaScript goes through a programming process before it is executed (other terms: create, pre-interpret process).

1.1 Macro perspective

  • create(contains the variable object, the parent scope context variable object).
  • create(Parameters, internal variables, function declarations).
  • Set up the.
PS: the creation process of variable objects
  • Create and initialize the argument object based on the function arguments.
  • Scan the code inside a function for a function declaration. For all function names and function references found, they are placed in the variable object. If a function with the same name already exists, it is overridden.
  • Scan the code inside the function and find the variable declaration. For any variable declaration found, put it in the variable object and initialize it to undefined. If the variable name is the same as the declared parameter or function, it will be ignored without interfering with the previous declaration.

1.2 Micro Angle

  • The process is to break the string into meaningful blocks of code called lexical units.
  • , the process is to abstract lexical units into abstract syntax tree AST.
  • . The AST generates code that can be executed.

2. After compiling, there is an execution phase.

2.1 Execution: values of variables, references to functions, and execution code.

1.For example, in code var a, the compiler asks if a variable with that name exists in the scope. If so, the compiler continues, and if not, a new variable is declared in the current scope.

At runtime, when the engine finds code a = 1, it first asks if there is a variable named a in the current scope, and assigns a value if there is.. In most cases, compilation occurs a few microseconds (or less) before the code is executed.

2, ES6 let, const

The new variable declaration syntax for ES is let and const. Let’s use let as an example.

function f() {
  console.log(a);
  let a = 2;
}
f(); // ReferenceError: a is not defined
Copy the code

Let and const have similar characteristics that prevent the variable from being promoted. When executing console.log(a), the variable is not defined, so the error is reported. In ruan yifeng’s website, it is also written that there is no variable improvement for let and const. The following

“, I also have doubts about this, and found that different authorities have different interpretations.

  • The MDN reads: In ECMAScript 2015, let do not support Variable Hoisting, which means the declarations made using “let”, do not move to the top of the execution block.

There is no variable promotion for let in MDN

  • Ecma-262-13.3.1 Let and Const Declarations let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated.

This means that even the let declaration on the last line of the block affects the first line of the block. That’s the hoisting power.

  • Ecma-262:8.2.1.2 Runtime Semantics: EvalDeclarationInstantiation (body, varEnv lexEnv, strict) wrote: The environment of with statements cannot contain any lexical declaration so it doesn’t need to be checked for var/let hoisting conflicts.

In the case of let collieries, that is, indirectly proving the existence of the following:

So you might wonder why this code is wrong. In fact, this is not due to the variable is not prompted, but due to TDZ (temporary dead zone).

Here’s an example:
{
    a = 2;
    let a;
}
Copy the code
This code can be interpreted as:
{
    leta; // Variable promotion"start TDZ"a = 2; // This is in the middle of TDZ, so error a = 2;"end TDZ"
}
Copy the code

So solved the case: let is the existence variable enhancement. It’s “variable promotion behavior,” which is caused by TDZ.

so… To summarize

  • The let declaration is promoted to the top of the block
  • From the top of the block to the variable’s initialization statement, this area is called TDZ (temporary dead zone).
  • If you use this variable in TDZ, JS will report an error. Note that TDZ is not equivalent to the following in the following cases: