[New features of ES6· (1)] Let and const declare variables in the new commands, don’t be stupid var!

Preface: The drawbacks of var declaration variables in ES5

ES5 actually provides us with two methods of declaring variables: varcommands and functioncommands. Using functioncommands to declare functions is not discussed here, we mainly compare varcommands.

Earlier, we explained in detail in the JS Getting Started article that varthere are three major characteristics of command declaration variables:

  • Variables can be declared repeatedly;
  • Variable declarations will be promoted;
  • No block-level scope;

These three characteristics make the writing of JS code seem a bit "random" and not standardized enough, and such grammatical logic is also counterintuitive. Give two examples:

  1. The inner variable will cover the outer variable
    with the same name: Below we vardeclare a global variable and numassign a value of 1, and then redeclare the variable showin the ifcode block of the function scope num, and assign a value of 2:
var num = 1;

function show() {
    
    
  console.log(num);
  if (false) {
    
    
    var num = 2;
  }
}

show();


——————OUTPUT——————
undefined

The final showfunction execution output result is undefined.
This is because the vardeclared variable has no block-level scope. The second redeclaration numwill be promoted to the beginning of the function, covering the outer global variable with the same name. At this time, the output result must be undefined. (All three characteristics are reflected in one example)

  1. The loop variables used for counting in various loop structures will be leaked as global variables: when
    we use loop structures, we will declare a loop control variable (such as i, j, k, etc.), but after the loop ends, it does not disappear , Leaked into a global variable.
for (var i = 0; i < 3; i++) {
    
    
  //...
}
console.log(i);


——————OUTPUT——————
2

A better approach is that we want it to be valid only in the loop control, and it will automatically fail after the loop ends and will not affect the execution of other parts of the code. At this time, we need to use the new letcommands in our ES6 .

1. Let and const basics

1.1 Basic usage of let

letCommands are new commands used to declare variables in the ES6 standard. Its mission is to replace varcommands. Its usage is similar var, but it makes up varfor design flaws.

The most fundamental difference between the two is that the letcommand can declare the current code block as a block-level scope (detailed in subsequent chapters), and letthe variables declared by the command are only valid in the current code block.
(The code block is in a pair of curly braces {})

{
    
    
  let a = 1;
  var b = 2;
}

a // ReferenceError: a is not defined.
b // 2

Access the variable outside the block of code awill be reported undefined error while using vardefined bvariables can still be accessed.

Now with the letcommand, you can solve the second problem at the beginning of this article: the problem of loop variable leakage. We use the statement of the forloop counter :ilet

for (let i = 0; i < 3; i++) {
    
    
  //...
}
console.log(i);


——————OUTPUT——————
// ReferenceError: i is not defined

The variable iis not accessible at this time .


❀ Expand a bit (1) ❀

letThere is another point to note when using commands in loops: variables iwill be redeclared each time in the loop .

Let's first look at using the vardeclared loop variable i, and add a timer function to print out this loop variable in each loop i:

for(var i = 0; i < 3; i++) {
    
    
    setTimeout(function() {
    
    
        console.log(i);
    }, 1000);
}


——————OUTPUT——————
3
3
3

Three 3s are output because the loop variable in the entire for loop is ialways the same variable, and finally the loop end variable iis assigned the value 2. Then change to the letcommand and output it again:

for(let i = 0; i < 3; i++) {
    
    
    setTimeout(function() {
    
    
        console.log(i);
    }, 1000);
}


——————OUTPUT——————
0
1
2

You can see that the output result is the same as without the timer function. This is because the variable iis re-declared every time in the loop. The reason why it is output according to the normal logic is that the JavaScript engine will remember the value of the previous round of loop. , When initializing the variables of this round, the icalculation is performed on the basis of the previous round.


❀ Expand a bit (2) ❀

The for loop itself has another special feature- the part that sets the loop variable is a parent scope, and the inside of the loop body is a separate child scope.

for (let i = 0; i < 3; i++) {
    
    
  let i = 'zevin';
  console.log(i);
}


——————OUTPUT——————
zevin
zevin
zevin

It was output 3 times zevin. This shows that the variables inside the loop body iand the loop variables iare not in the same scope, and have their own separate scopes.


1.2 Basic usage of const

constThe command is used to declare a read-only constant. It must be assigned at the beginning of the declaration, and cannot be changed once declared.

const PI;
// SyntaxError: Missing initializer in const declaration

const PI = 3.1415926;
PI = 3.14;
// TypeError: Assignment to constant variable.

❀ Expand it ❀

The essence of the const command

What the const command actually guarantees is not that the value of the variable cannot be changed, but that the data stored in the memory address pointed to by the variable cannot be changed.

For basic types of simple data (numerical value, string, Boolean value), the memory address pointed to by the variable stores the value itself, so it is equivalent to the value of the variable that cannot be modified;

const obj = {
    
    };

// 可以添加属性
obj.name = 'zevin';
console.log(obj.name);
// zevin

// 让obj指向另一个对象就会报错
foo = {
    
    }; 
// TypeError: "obj" is read-only

For reference data types (mainly arrays, objects), the memory address pointed to by the variable saves the reference address, but the reference address cannot be changed. For the array, the object itself, we can still add or delete element.


2. ES6 variable declaration new specification

In order to improve the situation in a statement ES5 var command, but also in order to improve the normative JS language, ES6 proposes the following four new variable declaration norms, letand constcommands are applicable.

2.1 Block-level scope

ES5 has only global scope and function scope. Finally, block-level scope has been added to ES6. Use letor constblock-level action command variable declared in a statement only where the domain is valid.

{
    
    
    let a = 1;
    if(true){
    
    
        const a = 2;
    };
    console.log(a);
}


——————OUTPUT——————
1

The code block is based on a pair of curly braces {}, which can be nested arbitrarily without affecting each other.

{
    
    {
    
    {
    
    {
    
    
  {
    
     const name = 'zevin' }
  console.log(name); 
  // 报错
}}}};

The above code uses a five-level block-level scope, each of which is a separate scope. The fourth-level scope cannot read the internal variables of the fifth-level scope.

2.2 There is no variable promotion

varThe variable declared by the command will be promoted to the beginning of the document or the beginning of the function, that is, the variable can be used before the declaration, and the value is undefined. And fixed the grammar in behavior ES6, letand constvariable command must be declared in a statement after use, otherwise an error.

console.log(a);
console.log(b);
console.log(c);

var a = 1;
let b = 2;
const c = 3;


——————OUTPUT——————
undefined
ReferenceError: Cannot access 'b' before initialization
ReferenceError: Cannot access 'c' before initialization

2.3 Temporary dead zone

ES6 clear that, if the block exists letand constcommand, this block these commands variable declarations, from the outset to form a closed scope. If these variables are used before the declaration, an error will be reported. This is grammatically called "temporal dead zone" (TDZ).

if (true) {
    
    
  // TDZ开始
  tmp = 'abc'; // ReferenceError
  console.log(tmp); // ReferenceError

  let tmp; // TDZ结束
  console.log(tmp); // undefined

  tmp = 123;
  console.log(tmp); // 123
}

In the above code, before the letcommand declares the variable tmp, all belong to tmpthe "dead zone" of the variable .


❀ Expand it ❀

The emergence of "temporary dead zone" also means that it is typeofno longer an operation that will never report errors.

typeof a; // undefined
typeof b; // ReferenceError
const b = 1;

Variable buse constbefore declaring variables belong to bthe "dead zone", as long as the use that variable error. Therefore, the typeofoperator will throw an ReferenceErrorerror.

But if a variable is not declared (variable a) at all, typeofit will not report an error when used undefined.


2.4 Duplicate declarations are not allowed

ES6 does not allow multiple declarations of the same variable in the same scope.

if(true){
    
    
    var a = 1;
    let a = 2;
    const a = 3;
}
// SyntaxError: Identifier 'a' has already been declared

Therefore, in the same way, the variable with the same name as the formal parameter cannot be used letor constcommanded in the function , but it varcan.

function func(num) {
    
    
  let num = 1;
  console.log(num);
}
func() 
// SyntaxError: Identifier 'num' has already been declared
function func(num) {
    
    
  var num = 1;
  console.log(num);
}
func() 
// 1

Since different block-level scopes do not affect each other, we can define variables with the same name in different block-level scopes. So the following code will not report an error:

function func(num) {
    
    
    var num = 1;
    if(true){
    
    
        let num = 2;
    }else{
    
    
        const num =3;
    }
  }
  func()

3. Extension: Six ways to declare variables in ES6

ES5 ES6
var
function
let
const
import
class

ES6 in fact, four new variable declaration methods: This paper introduces the letcommands and constcommand, follow-introduced again importcommands and classcommand. Coupled with the varcommands and functioncommands in ES5 , there are six ways to declare variables in ES6.

Guess you like

Origin blog.csdn.net/JZevin/article/details/108369123