ES6 learn the let and const commands in Chapter 1

Keywords: Javascript ECMAScript

preface:

Recently, I began to read teacher Ruan Yifeng's introduction to ECMAScript 6 (hereinafter referred to as the original text), learn the knowledge of ECMAScript 6 (hereinafter referred to as ES6), sort out some knowledge points and my understanding to make article notes. According to the chapter as a unit, a chapter is a note.
The article code is different from the directory structure and the original text.

Link to the original text of this chapter let and const commands .

let

let is used to declare a variable.
Different from var, there will be variable promotion (described below). The variable value declared by let is only valid in the code block where the let command is located.
The same scope (described below) cannot use let to declare the same variable repeatedly.

be careful:

  • Declare variable
  • No variable promotion
  • Non repeatable declaration
  • Only valid in the code block where the let command is located
let sample = 1;
sample = 2;
let sample = 2; // An error will be reported
{
  let sample = 1;
  console.log(sample); // Normal output 1
}

console.log(sample); // An error will be reported because it is only valid in the code block where the let command is located

const

const is used to declare a read-only constant.
Once declared, the value of the constant cannot be changed. If you try to change the value of a constant, an error will be reported.
And const must assign a value to it when it is declared. If it only declares that it does not assign a value, an error will be reported.
const cannot be used to declare the same constant repeatedly in the same scope.
const, like let, can only be valid in the code block because of scope.

const actually guarantees that the value of the variable cannot be changed, but the data stored at the memory address pointed to by the variable cannot be changed.

be careful:

  • declare constant
  • It cannot be changed after declaration
  • You must assign a value to it when you declare it
  • Non repeatable declaration
  • Valid in the code block where const command is located
const sample = 1;
sample = 2; // An error will be reported. The variable declared by const cannot be re assigned
const sample; // If an error is reported directly, it must be assigned when const is declared

let and const

After the introduction of let, var can be replaced. If const can be used between let and const, try to use const.

let differs from const

The difference between let and const is that a declared variable is a declared constant. Variables can be re assigned, but constants cannot be re assigned.

let sampleLet = 2;
const sampleConst = 1;

sampleLet = 3; // normal
sampleConst = 3; // report errors 

let is the same as const

  • Can only be declared before use, and variable promotion is not allowed.
  • Cannot be declared repeatedly in the same scope
  • Are valid only in the code block where the command is located
{
sampleLet; // report errors
sampleConst; // report errors
  
let sampleLet = 2;
const sampleConst = 1;
  
let sampleLet = 3; // report errors
const sampleConst = 3; // report errors
}

sampleLet; // report errors
sampleConst; // report errors 

Variable lifting

Before ES6, when variables were declared with var, a feature called variable promotion was produced.
No matter where it is declared in the code, it will be promoted to the top of the current scope. This behavior is called variable promotion.
In order to correct this phenomenon, the let command changes the syntax behavior. The variables it declares must be used after declaration, otherwise an error will be reported

let and const above indicate that variables cannot be promoted. Is that true?
In fact, in JavaScript, all represent var,   let,   const,   function,   function*, class declarations will be promoted.
let and const declare variables are created when the environment is instantiated, but they are not allowed to be accessed in any way before the lexical binding of variables. That is to say, when you declare variables before the declaration, they will be wrong, but the error message is not undefined but can not be accessed before initialization. This leads to the next concept, called temporary dead zone.

// var declaration will promote the variable without error, but the value is undefined
console.log(sampleVar); // undefined
var sampleVar = 1;

// let declaration does not promote variables, but the error is not defined
console.log(sampleLet); // Cannot access 'sampleLet' before initialization
let sampleLet = 1;

// const declaration will not promote variables, but the error is not defined
console.log(sampleConst); // Cannot access 'sampleConst' before initialization
const sampleConst = 1;

// If you directly use undeclared variables, the error is "is not defined"“
console.log(sample); //sample is not defined

Temporary dead zone

ES6 stipulates that if there are variables declared by let and const commands in the code block, the block forms a closed scope for these variables from the beginning. If these variables are used before declaration, an error will be reported. These variables can not be accessed (obtained or set) until the declaration statement is completed,
This is called "temporary dead zone" (TDZ) in syntax, that is, the area from the beginning of the code block to the completion of the variable declaration statement.

var sample = 1;
if (true) {
  sample = '1';  // report errors
  let sample;
}

In short, the variables declared by let and const commands already exist when entering the scope of the declaration code, but they cannot be obtained or used until the declaration statement is completed.

Block level scope

Scope is the accessible scope of variables and functions, that is, the scope controls the visibility and life cycle of variables and functions.

let and const block level scopes

Scope is not a new thing in ES6, but in ES5, there are only global scope and function scope. In order to solve the block level scope, ES6 can use * * let * * and * * const * * to declare variables of a block level scope
The variables declared by var have the characteristics of variable promotion, so there is no block concept and can be accessed across blocks, but not across functions.
The outer scope cannot read variables from the inner scope.

{ // Block scope
  var sampleVar = 1;
  let sampleLet = 2;
  const sampleConst = 3;
  console.log(sampleVar); // Successful output 1
  console.log(sampleLet); // Successful output 2
  console.log(sampleConst); // Successful output 3
}
console.log(sampleVar); // Successful output 1
console.log(sampleLet); // Error not defined
console.log(sampleConst); // Error not defined


ES6 allows arbitrary nesting of block level scopes.
The same scope cannot use let or const to declare the same variable. The inner scope can define variables with the same name as the outer scope.

{
  {
    {
      let sample = 'Hello World'; // Outer scope
      { let sample = 'sample'; } // No error reporting
      { console.log(sample); }  // Normal output 'Hello World'
    }
  }
}

Block level scope and function declaration

ES5 stipulates that functions can only be declared in the top-level scope and function scope, not in the block level scope.
ES6 stipulates that in the block level scope, the behavior of the function declaration statement is similar to * * let * *, and cannot be referenced outside the block level scope.

/* 
    ES5,Both cases are illegal because both function declarations are declared in the block scope.
  However, in order to be compatible with the previous old code, the browser still supports the declaration of functions in the block level scope, so there will be no error
*/ 

if (true) {
  function sampleFn() {}
}

try {
  function sampleFn() {}
} catch(e) {
  // ...
}
/* 
    ES6,A function declaration statement behaves like a let and is not referenced outside the block level scope
*/ 

if (true) {
  sampleFn();  // In normal output, the function declaration statement behaves like a let
  function sampleFn() {
    console.log('Hello World');
  }
}

// However, functions can also be referenced outside the block level scope, but the value is undefined

if (false) {
  function sampleFn() { console.log('Hello World'); }
}
console.log(sampleFn); // Normal output undefined
sampleFn(); // The error is samplefddddn is not defined 

Why can functions be referenced outside the block level scope?
If you change the processing rules of functions declared in the block level scope, it will obviously have a great impact on the old code. In order to reduce the incompatibility caused by this, ES6 stipulates in Appendix B that the browser implementation can not comply with the above provisions (referring to the behavior of function declaration statements) and have its own behavior.

  • Allows functions to be declared within a block level scope.
  • Function declarations are similar to * * var * *, that is, they are promoted to the head of the global scope or function scope.
  • At the same time, the function declaration is promoted to the head of the block level scope.

Note that the above three rules are only valid for the browser implementation of ES6. The implementation of other environments does not need to comply with them. The function declaration of the block level scope is still treated as a let.

We should avoid declaring functions within a block level scope. If necessary, it should also be written as a function expression rather than a function declaration statement.

// The function declaration statement should not be used in the block scope because there will be variable promotion
{
  function sampleFn() {
    console.log("Hello World");
  }
}

// Function expression. In the block scope, the function will not have variable promotion
{ 
  const sampleFn = function () {
    console.log("Hello World");
  }
}

Top level object

The top-level object refers to the window object in the browser environment.
In ES5, the properties of top-level objects are equivalent to global variables.
ES6 to change this,
On the one hand, in order to maintain compatibility, the global variables declared by var command and function command are still the attributes of the top-level object;
On the other hand, it is stipulated that the global variables declared by let command, const command and class command do not belong to the properties of the top-level object.

/*
    ES5 The attribute assignment of the top-level object is the same as that of the global variable.
*/

window.sample = 1;
console.log(window.sample); // Normal output 1
sample = 2;
console.log(window.sample);// Normal output 2

/*
    ES6 The global variables declared by let command, const command and class command do not belong to the properties of the top-level object.
*/

var sampleVar = 1;
console.log(window.sampleVar)  // Normal output 1
let sampleLet = 1;
console.log(window.sampleLet) // Normal output undefined
let sampleConst = 1;
console.log(window.sampleConst) // Normal output undefined

window provides a global environment (i.e. global scope) in which all code runs.

This in the function, if the function is not run as a method of the object, but simply as a function, this will point to the top-level object. However, in strict mode, this will return undefined.
Whether in strict mode or normal mode, new Function('return this') () always returns a global object.

function sampleFn(){
  console.log(this);
}
sampleFn(); // Normal output global object window

function sampleFn1(){
  "use strict";
  console.log(this)
}
sampleFn1(); // Normal output undefined

// Turn on strict mode
"use strict";
const sample  = new Function('return this')();
console.log(sample); // Normal output global object window

Posted by David03 on Mon, 22 Nov 2021 23:34:38 -0800