In 2021, if you still have var in your JavaScript code, you should move to let or const as soon as possible. This is a new keyword in ES6.

  1. Avoid variable promotion (create temporary dead zones)
  2. Block-level scope support (avoid global variable contamination)

Avoid variable promotion

Variable promotions are a pain in the heart of JavaScript programmers, such as:

console.log(a)
var a = 1
Copy the code

Undefined. This code would be an error in almost any other major language. In school, we were taught to use variables before they were declared.

Yes, JavaScript is so magical that it has a concept of “variable promotion”, which means that the above code is equivalent to:

var a
console.log(a)
a = 1
Copy the code

This feature of VAR can cause hidden problems for developers, such as the following code:

var name = 'David'
function test() {
  / /... Here's a lot of business code
  // Suddenly want to access the global variable name
  console.log(name)
  / /... Again, lots of business code
  // Accidentally define a temporary variable also called name
  var name = 'Lucy'
}

test()
Copy the code

If the middle name is undefined, you will be confused, but if you change it to let, everything will be fine, because you will get an error:

ReferenceError: Cannot access 'name' before initialization
Copy the code

The variable is not available within the code block until it is declared using the let command. This is grammatically known as a “temporal dead zone” (TDZ). The main purpose is to reduce runtime errors and prevent unexpected behavior by using a variable before it is declared.

The essence of a temporary dead zone is that all variables already exist as soon as the current scope is entered, but cannot be used until they are declared.

Block-level scopes are supported

ES5 has only global and function scopes. There is no scope for a scope wrapped in curly braces, for example:

{
  let a = 1
  var b = 2
}

console.log(a) // ReferenceError: a is not defined.
console.log(b) / / 2
Copy the code

If we use var to declare a variable, we will pollute the whole world. If we use let to declare a variable, we will pollute the whole world.

for (var j = 0; j < 10; j++) {
  // ...
}
console.log(j) / / 10


for (let i = 0; i < 10; i++) {
  // ...
}
console.log(i) // ReferenceError: i is not defined
Copy the code

When declaring loop variables in let, do you think the scope of I is the body of the loop wrapped in curly braces? This is not true, because I is not defined in the body of the loop. In fact, the scope of I is the part that sets the variable of the loop, namely the for statement. Inside the body of the loop, there is a separate subscope.

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc
Copy the code

The above code does not report an error, but prints ABC three times, indicating that the variable I inside the function and the loop variable I are not in the same scope and have separate scopes (because the same scope cannot be declared repeatedly using let). When a for loop has asynchronous operations, the difference between var and let is obvious. For example:

for (var j = 0; j < 10; j++) {
  setTimeout(() = > console.log(j), 100) // Prints 10 10s
}

for (let i = 0; i < 10; i++) {
  setTimeout(() = > console.log(i), 100) // Prints 0 to 9
}
Copy the code