Brief discussion on the difference between LET and VAR

About the var

First, let’s take a look at MDN’s explanation of VAR:

1: Variable declarations, no matter where they occur, are processed before any code is executed. (variable promotion) 2: Declared variables are limited in scope to the context in which they are declared, and non-declared variables are always global 3: If you redeclare a JavaScript variable, it will not lose its value... .Copy the code

I’ve only excerpted a few features, but they should give us an idea of the differences between var and let. Before we talk about the differences between var and let, let’s take a quick look at these features of VAR.

Variable promotion and scope of VAR

Let’s start with an interview question: What will the following code print?

var a = 99;
f();
console.log(a);
function f(){
    console.log(a);
    var a = 10;
    console.log(a);
}
Copy the code

How to improve the scope of a variable

var a;
function f(){
    var a;
    console.log(a); 
    a = 10;
    console.log(a); 
}
a = 99;
f();
console.log(a);
Copy the code

The result is:

undefined
10
99
Copy the code

The first console.log printed in function F has been declared in scope f, but has not yet been assigned a value. The second console.log inside f prints the assigned a, which is still a in the function’s scope, so it prints 10. The a in console.log at the end of the code is the a of the current scope, the global variable, which is declared and assigned to 99, so the final result is 99. If you fully understand the topic, then you should understand the variable promotion and scope of VAR.

Accidentally declare a global variable

Let’s start with an example of MDN:

function x() {
  y = 1;   // ReferenceError is raised in strict mode
  var z = 2;
}
x();
console.log(y); // Prints the result 1
console.log(z); // ReferenceError: z is not declared outside x
Copy the code

Inside the function of x, we not to make any statement but y variable directly on the assignment, in so doing, we carelessly declared a global variable, our intention is a function in the internal declare a local variable x, but use the console. The outside of the function x log, also can print out the value of y, in fact, the above code is equivalent to:

var y = 1;
function x(){
    var z;
    y = 1;
    z = 2;
}
x();
console.log(y);
console.log(z);
Copy the code

On the third point

3: If you redeclare a JavaScript variable, it will not lose its valueCopy the code

As for the third explanation, let’s translate it in our own words

Var can repeatedly declare a variable, but no matter how it is declared, it is the same variable in the current scope. OkayCopy the code

As confusing as it sounds, let’s look at the code:

<div id=parent></div>= = = = = = = = = = = = = = = = = = = = = > I am line < = = = = = = = = = = = = = = = = = = = = = in the script tag:var parent = document.getElementById('parent'); Ask yourself:console.log(parent);
console.log(window.parent); What do these two results print out in the browser console?Copy the code

The answer is:

The result is: div element with id parentCopy the code

In fact, we declare an already declared global property, window.parent: returns the parent window if there is a parent window; If not, return to the current window. In this case, we declare parent again, and we assign a value to the declared variable, overwriting the global property parent. In other words:

var a = 1;
var a = 2;
var a = 3;
var a = 4;
console.log(a);
Copy the code

There are no syntax errors in this code, but it is equivalent to:

var a;
a = 1;
a = 2;
a = 3;
a = 4;
console.log(a);
Copy the code

About the let

Let’s first look at MDN’s interpretation of let:

1: letThe scope of var is a block, while the scope of var is function 2: a scopeletRedefining a variable raises TypeError... .Copy the code

Let’s explanation, I only excerpted part of it, if you want to know more details, you can search MDN~~~

Scope of let

Like var, let declares variables that are only available in the block or subblock it declares. The main difference between the two is that the scope of the variable declared by var is the entire enclosing function. The following is an example:

{
    var dobby = Awesome!;
}
console.log(dobby); // Print 666
{
    let kim = Awesome!;
}
console.log(kim); // ReferenceError, Kim is not defined
Copy the code

MDN example is more vivid, I borrowed to use: -)

function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // Same variable!
    console.log(x);  / / 2
  }
  console.log(x);  / / 2
}

function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // Different variables
    console.log(x);  / / 2
  }
  console.log(x);  / / 1
}
Copy the code

As can be seen from the above example, let scope, let’s go back and look at this problem again:

<div id=parent></div>= = = = = = = = = = = = = = = = = = = = = > I am line < = = = = = = = = = = = = = = = = = = = = = in the script tag:var parent = document.getElementById('parent');
Copy the code

If we have to use a variable like parent (which we certainly don’t recommend, because global attributes are shameful!) , let it represent the div element with id parent, and we want the global attribute window.parent to remain intact

{
    let parent = document.getElementById('parent');
    console.log(parent);
}
console.log(window.parent);
// In addition, you can also use the immediate function, because again, var is scoped as a function
(function(){
    var parent = document.getElementById('parent');
    console.log(parent);
}).call();
Copy the code

Let has no variable promotion

Unlike var, let has no variable promotion, no variable promotion, and no variable promotion. A good example from MDN 🙂

function do_something() {
  console.log(bar); // undefined
  console.log(foo); // ReferenceError: foo is not defined
  var bar = 1;
  let foo = 2;
}
Copy the code

Let’s take a look at Ruan Yifeng’s explanation:

ES6 clearly states that if a block existsletAnd const commands. The variables declared by the block for these commands are closed in scope from the start. Any time these variables are used before declaration, an error is reported. In short, within the code block, useletThe variable is not available until the command declares it. This is grammatically called a temporary dead zone (TDZ).Copy the code

In fact, a simple summary is that there is no variable promotion in LET, which is one of the differences between LET and VAR

Repeating the let variable definition causes an error

Example:

{
    let dobby = 1;
    let dobby = 2;// TypeError thrown.
}
Copy the code

Nothing to explain 🙂

An interview question

for (var i = 0; i <10; i++) {  
  setTimeout(function() {  
    console.log(i);        
  }, 1000);
}
Copy the code

with

for (let i = 0; i <10; i++) {  
  setTimeout(function() {  
    console.log(i);        
  }, 1000);
}
Copy the code

What is the result of printing the two codes?


This is an interview question that has been played badly, because I have not learned the JS event loop mechanism, if REALLY let me tell the reason why, I really can not carry on the detailed explanation, but in the follow-up, I will continue to write a separate blog on this question, take a good in-depth study of the mechanism and mystery ~

The var loop results in 10 10sletThe results of the loop are: 0,1,2,3,4,5,6,7,8,9Copy the code

In fact, we can also simply carry out a wave of analysis, for var loop, we can write:

var i;
for (i = 0; i <10; i++) {  
  setTimeout(function() {  
    console.log(i);        
  }, 1000);
}
Copy the code

Because of var’s variable promotion mechanism, we are essentially declaring a global variable. Review this code:

var a;
a = 1;
a = 2;
a = 3;
a = 4;
console.log(a);
Copy the code

In the var loop, the I that we print is actually the only variable in the world, so it prints 10 10s; In the case of the let loop, we recall the scope of the let. When I is used in the for loop block, there is no external influence.

conclusion

What are the differences between var and let?

  1. Var is scoped as a function, while let is scoped as a block
  2. Var has variable promotion, while let does not
  3. Var can be redefined, but within a scope the redefinition is just that variable, and redefining a let variable raises TypeError

If there is any mistake, please also point out, very grateful ~