The original link: dmitripavlutin.com/variables-l…

Promotion is actually the process of moving variables and function definitions to the top of the scope. It usually occurs with the variable declaration var or function declaration function fun() {… }.

When let (including const and class that have the same declarative behavior as let) was introduced in ES2015, many developers, myself included, used promotions to describe how variables were accessed. But after doing some more searching on this issue, I was surprised to learn that promotion is not the right term to describe let variable initialization and availability.

ES2015 provides a different and improved mechanism for LET. It requires stricter variable declaration practices (which cannot be used before definition), resulting in higher quality code.

Let’s look at this process in more detail.

1. Error-pronevarascension

Sometimes I see a strange practice, var varname and function funcName() {… } declare anywhere in the scope:

// var hoisting num; // => undefined var num; num = 10; num; / / / / = > 10functionhoisting getPi; / / = >function getPi() {... } getPi(); / / = > 3.14function getPi() {  
  return 3.14;
}
Copy the code

The num variable is called before the var num declaration, so it is assumed to be undefined.

Function getPi() {… } is defined at the end. Since it is elevated to the top of the scope, the function can be called before getPi() is defined.

This is a classic ascension.

It turns out that using variables or functions later can be confusing. Suppose you’re scrolling through a large file and suddenly see an undeclared variable… How did it come to be here and where was it defined?

Of course, an experienced JavaScript developer wouldn’t write code this way, but there are probably thousands of JavaScript GitHub repositories out there with code like this.

Even looking at the code examples given above, it is difficult to understand the declaration flow in the code.

Naturally, declare or describe an unknown word first, and then use it to write a phrase. Let encourages using variables in this way.

2. Explore the bottom line: the life cycle of variables

When the engine accesses variables, their life cycle consists of the following phases:

  1. Declaration phase: Registers a variable in scope
  2. Initialization phase: Allocates memory and creates bindings for variables in scope. At this stage, variables are automatically initialized toundefined
  3. Assignment phase: Assigns values to variables that have already been initialized

Variables that pass through the declaration phase but do not reach the initialization phase are in an undefined state.

Note that declaration phase and general variable declaration are different terms depending on the life cycle of a variable. In short, the engine handles variable declarations in three phases: the declaration phase, the initialization phase, and the assignment phase.

3.varThe life cycle of a variable

Familiar with life cycle phases, we use them to describe how the engine handles var variables.

var

Where var variable is declared in function scope does not affect the declaration and initialization phases.

After the declaration and initialization, and before the assignment phase, the variable is undefined and accessible.

In the assignment phase, variable = ‘value’, the variable gets its initial value (step 2).

Strictly speaking, the concept of promotion is to declare and initialize variables at the top of a function’s scope. There is no gap between the declaration and initialization phases.

Let’s look at an example. The following code creates a function with the var variable:

functionmultiplyByTen(number) { console.log(ten); // => undefined var ten; ten = 10; console.log(ten); / / = > 10returnnumber * ten; } multiplyByTen(4); / / = > 40Copy the code

When JavaScript starts executing multipleByTen(4), it enters the function scope of multipleByTen, and the variable ten completes the declaration and initialization phase before the first statement. So a call to console.log(ten) prints undefined.

The statement ten = 10 assigns an initial value. After allocation, console.log(ten) correctly prints 10.

4. The life cycle of function declarations

Suppose a function declaration statement function funName() {… }, this is easier.

funcName()

The following code example shows function promotion:

function sumArray(array) {  
  return array.reduce(sum);
  function sum(a, b) {
    returna + b; } } sumArray([5, 10, 8]); / / = > 23Copy the code

When JavaScript calls sumArray([5, 10, 8]), it enters the function scope of sumArray. In scope, sum passes through three phases: declaration, initialization, and assignment before any statement is executed. Array.reduce (sum) can even be declared in function sum(a, b) {… } before using sum.

5.letThe life cycle of a variable

The let variable is handled differently than var. The main difference is that the declaration and initialization phases are separated.

let variable

The interpreter then parses the statement line by line.

If you try to access variable at this stage, JavaScript raises ReferenceError: variable is not defined. Because the state of a variable is undefined, variable is in a temporary dead zone.

When the interpreter reaches the let variable statement, the initialization phase passes (Step 2). The state of the variable is now defined and accessing it returns undefined.

The variable exited the temporary dead zone.

Later, when the assignment statement variable = ‘value’ occurs, the assignment phase (step 3) is passed.

If JavaScript encounters let variable = ‘value’, initialization and assignment will occur on this statement.

Let’s look at an example. Declare a variable in a block-level scope with let:

let condition = true;  
  // console.log(number); // => Throws ReferenceError
  letnumber; console.log(number); // => undefined number = 5; console.log(number); / / = > 5}Copy the code

When JavaScript enters if (condition) {… } block level scope, number immediately passes through the declaration phase. Because number is in an undefined state, in a temporary dead zone, attempts to access this variable raise a ReferenceError: Number is not defined.

Later, the statement let number completes the initialization. This variable is now accessible, but its value is undefined.

The assignment statement number = 5 completes the assignment phase.

Const and class types have the same life cycle as lets, except that assignment can occur only once.

5.1 Why is promotion inletIs invalid during the life cycle of

As mentioned above, promotion is when variables are declared and initialized at the top of the scope. But the let life cycle decouples the declaration and initialization phases. Decoupling invalidates the term lift.

The gap between the two phases creates a temporary dead zone where variables cannot be accessed.

In a sci-fi style, the collapse of the term ascension creates a temporary dead zone in the LET lifecycle.

Conclusion 6.

Using var arbitrarily to declare variables is a mistake. Based on this lesson, ES2015 created let. It uses an improved algorithm to declare variables and uses block-level scope.

Because the declaration and definition phases are decoupled, promotion does not apply to variables declared by a let (including const and class). Variables are in a temporary dead zone and inaccessible until initialized.

Keep variable declarations stable with the following suggestions:

  • Declare, initialize, and then use variables. This process is correct and easy to follow;
  • Hide variables if possible. The less variables are exposed, the more modular your code becomes.