preface

Prior to ES6, JavaScript only had the classic VAR declaration, which caused a lot of frustration for developers. With the advent of ES6, the let and const keyword declarations were added. Variable declaration, scope, state promotion.


Scope/execution context

In the JavaScript world, there are three types of scope: global scope, function scope, and block-level scope.

  • Global scope/execution context: the default or most basic scope. A program has only one global scope and is at the bottom of the execution stack for the lifetime of a JavaScript script without being popped for destruction. There is one global object in the global scope (in the case of the browser environment, the global object is window).
  • Function scope: Inside a function body is a scope.
  • Block-level scope: exists in blocks — characters{}The area between. (Obviously the function body is also enclosed by curly braces, so the function scope is also block-level.)

The var statement

The var declaration in the global scope is added to the global object as a property of the global object. In function scope, it is promoted to the top of the function. And function declarations are promoted during the precompilation phase, regardless of whether they are actually executed, leaving initialization locally.

  • Variables declared by var are promoted to the top of the current scope (the current scope only includes global scope or function scope, not block-level scope).

Block-level statement

Temporary Dead Zone (TDZ) : Term used to describe the non-promotion effects of lets and const. When the JavaScript engine scans the code for variable declarations, it either promotes them to the top of the scope (var declarations) or places them in the TDZ (let and const declarations). Accessing a variable in the TDZ triggers a runtime error, and the variable is removed from the TDZ only after the variable declaration statement has been executed before it can be accessed normally.

Const and let are block-level identifiers, so declared variables and constants are only valid in the current code block and are immediately destroyed once executed outside the block.

  • Let declaration: You can limit the scope of variables to the current code block. Variables are placed in a temporary dead zone before statements are declared.
  • Const declaration: Used to declare constants, and each constant declared by const must be initialized. If it is an object, the value in the object can be changed (coSNT states that binding is not allowed to be changed, but binding values can be changed)

Undeclared variables

In JavaScript, you can define a variable without a keyword declaration without an error. But it’s not recommended.

A statement such as a = 0 creates an attribute of A on the window object, whether in the global, function, or block scope, in effect executing window.a = 0. Only in the global scope will var a = 0 create the property a on the window, which is window.a = 0.

1. Declare variables without keywords

function func() {
    b = 0
    console.log(b);
    console.log(b === window.b);
}
func()
console.log(b === window.b);

// Output the result
/*
0
true
true
*/
Copy the code

👆👆 this part of the code executes the func function, taking the variable B as an attribute of the window object.

2. Use variables declared by var

function func(x) {
    var b = 0
    console.log(b);
    console.log(b === window.b);
}
func(1)            
console.log(b === window.b);

// Output the result
/* 0 false Uncaught ReferenceError: b is not defined */
Copy the code

👆👆 This code is normal var declaration variables in the function scope promotion.

Var declarations and block-level declarations

Global scope binding

  • When var is declared in global scope, a new global variable is created as a property of the global object (window object in browsers). This means that using VAR can inadvertently overwrite a global variable that already exists.
  • Block-level declarations (let or const) create a new binding in the global scope, but the binding is not added as a property of the global object. So block-level declarations do not overwrite a global variable, only mask it.
let RegExp = 'Hello! '
console.log(RegExp);
console.log(window.RegExp === RegExp);
/ / the result
/* Hello! false */
Copy the code

State of ascension

  • The variable declared by var is promoted to the top of the current scope before instantiationundefined. Variables declared by var are limited to global scope or function scope.
  • Block-level declared variables are placed in a temporary dead zone and can be accessed with an error before instantiationUncaught ReferenceError
console.log(RegExp);
let RegExp = 'Hello! '
// Uncaught ReferenceError: Cannot access 'RegExp' before initialization
Copy the code

Best practices for block-level binding

Use the defaultconstOnly when you really need to change the value of a variablelet.


Function declaration promotion

Function promotion takes precedence over variable promotion.

Function declarations are promoted to the top of the current scope and can be accessed anywhere within the current scope.


reference

In Depth ES6 chapter 1, block-level scope binding