preface

The difference between var, let and const is an old question and a classic interview question. This article will give you a comprehensive overview of the three characteristics, and the differences between them, to get you through the basics.

Variable declarations

ECMAScript variables are loosely typed, meaning that variables can be used to hold any type of data, and each variable is nothing more than a named placeholder to hold arbitrary values.

There are three keywords to declare variables: var, let, and const. Var is available in all versions of ECMAScript, while let and const are available only in ES6 and later.

var

To define a variable, use the var operator (note that var is a keyword), followed by the variable name (that is, the identifier, as described earlier) :

var message;
Copy the code

The above line defines a variable named Message, which can hold any type of value. Uninitialized, the variable holds a special value called undefined.

ECMAScript implements variable initialization, so you can define a variable and set its value at the same time:

var messgae = "hi";
Copy the code

Message is defined as a variable that holds the string value “hi”. Initializing a variable like this does not identify it as a string, just a simple assignment. You can then change not only the saved value, but also the type of the value:

var message = "hi"; message = 666; Console.log (message) is not recommended. / / 666Copy the code

If you need to define multiple variables, separate each variable (and optional initialization) in a single statement with a comma:

Var message, name = "sun Wukong ", age = 18;Copy the code

scope

A variable defined using the var operator becomes a local variable of the function that contains it. For example, using var to define a variable inside a function means that the variable will be destroyed when the function exits:

function test() { var message = "hi"; } test(); console.log(message); // error: message is not definedCopy the code

However, by omitting the var operator when defining variables inside a function, we can create a global variable:

function test() { message = "hi"; } test(); console.log(message); // okCopy the code

While it is possible to define global variables by omitting the var operator, this is not recommended. In strict mode, an error is reported if an undeclared variable is assigned like this.

It’s ok to use var to declare the same variable multiple times in the same scope:

function test() { var message = "hi"; var message = false; var message = 666; console.log(message); } test(); / / 666Copy the code

ascension

The promotion is to pull all variable declarations to the top of the function scope. Note that only the declaration is promoted, not the assignment operation.

Here’s an example:

function test() {
    console.log(message);
    var message = "hi";
}
test(); // undefined
Copy the code

The above code does not return an error because variables declared using the var keyword are promoted to the top of the function scope, which is equivalent to the following code:

function test() {
    var message;
    console.log(message);
    message = "hi";
}
test(); // undefined
Copy the code

let

Let and VAR have similar functions, but there are very important differences.

scope

Var declares function scope and let declares block scope:

if (true) {
    var message = "hi";
    console.log(message); // hi
}
console.log(message); // hi


if (true) {
    let message = "hi";
    console.log(message); // hi
}
console.log(message); // error: message is not defined
Copy the code

The message variable cannot be referenced outside the if block because its scope is limited to that block. Block scopes are subsets of function scopes, so the same scope restrictions that apply to var also apply to LETS.

Let does not allow redundant declarations in the same block scope:

If (true) {// error: cannot redeclare block scope variable "a" let a; let a; }Copy the code

The JS engine keeps track of the identifiers used for variable declarations and the block scope in which they are located, so nesting the same identifiers will not report an error because there are no duplicate declarations in the same block:

let a = 666; console.log(a); // 666 if (true) {let a = 'ah-ha '; console.log(a); //Copy the code

Var and let do not declare different types of variables, they just indicate how variables exist in the relevant scope, so declaration redundancy is not affected by mixing var and let:

// error
var a;
let a;

// error
let b;
var b;
Copy the code

Temporary dead zone

Variables declared by let are not promoted in scope:

if (true) { console.log(x); // error: use variable "x" before assignment let x = 520; }Copy the code

When parsing code, the JS engine also pays attention to let declarations that appear after blocks, but undeclared variables cannot be referenced in any way before then. The moment of execution before the LET declaration is called a temporary dead zone, and references to any variable declared later in this phase will result in an error.

const

Const behaves in much the same way as let, with the only important differences being that a variable declared by const must be initialized at the same time, and attempts to modify a variable declared by const result in an error:

const a; // error: "const" must be initialized to declare const b = 250; b = 520; // error: cannot assign to "b" because it is a constantCopy the code

Note that the const declaration restriction applies only to references to the variable to which it refers. In other words, if a const variable refers to an object, then modifying properties inside that object does not violate the const constraint:

const obj = { x: 666 }; obj.x = 888; // ok obj. Y = 'ah-ha '; // okCopy the code

extension

Global declarations

Variables declared in global scope with var become properties of the window object. Variables declared in let and const do not:

var a = 666;
console.log(window.a); // 666

let b = 666;
console.log(window.b); // undefined

const c = 666;
console.log(window.c); // undefined
Copy the code

Let declaration in the for loop

First look at 🌰 :

for (var i = 0; i < 5; i++) {
    ...
}
console.log(i);
Copy the code

Think about it, what would be the print result?

Since the variable declared by var has no block scope, the iterating variable I penetrates outside the loop body and exits the loop when I increments to 5, printing a result of 5.

If we declare the iterating variable with let, we can limit the scope of the iterating variable to the inside of the for block:

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

Here’s another chestnut:

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

You might expect it to print: 0, 1, 2, 3, 4, but it will actually print: 5, 5, 5, 5.

The reason for this is that when the loop exits, the iteration variable holds the value that caused the loop to exit, namely 5. When the timeout logic is then executed asynchronously, all the I’s are the same variable, so the output is the same final value.

Each setTimeout refers to a different instance of the variable, so console.log outputs the desired value, that is, the value of each iteration variable during the execution of the loop:

for (let i = 0; i < 5; i++) { setTimeout( () => { console.log(i); // 0, 1, 2, 3, 4}, 0)}Copy the code

This is a classic interview question, not very understand words must read several times, the best hands-on practice, thoroughly understand so far.

conclusion

  • Var is declared in function scope, and let and const are declared in block scope

  • Variables declared by var are promoted to the top of the function scope. Variables declared by let and const are not promoted and have temporary dead zones

  • Var allows the same variable to be declared repeatedly in the same scope. Let and const do not

  • Variables declared with var in the global scope become properties of the window object. Variables declared with let and const do not

  • Const behaves much the same as let, with the only important difference that variables declared with const must be initialized and cannot be modified

Declare style and best practices

The addition of lets and const in ECMAScript 6 objectively provides better support for the language to declare scope and semantics more precisely, and the JS community has been plagued for years by problems caused by misbehaving var. With the advent of these two keywords, new best practices that help improve code quality are emerging.

Var is obsolete and not recommended. Limiting yourself to lets and const helps improve code quality because variables have clear scopes, declared locations, and unchanging values.

Const is preferred, let is second. Using const declarations allows the browser runtime to force variables to remain unchanged, and static code analysis tools to detect illegal assignments ahead of time. Use lets only if you know in advance that changes are coming. This allows developers to infer with greater confidence that certain variables will never change in value, and can also quickly detect unexpected behavior due to unexpected assignments.

The last

If there are any mistakes or inadequacies in this article, you are welcome to correct them in the comments section.

Your thumbs-up is a great encouragement to me! Thanks for reading ~