Github Notes: Front-end-Basics

Note address for this article: a change arising from block-level scope

ES6 walk and see series, special song Xie Qi dance reading club ~


Block-level scope, also known as lexical scope, exists in:

  • Inside a function (function scope)
  • Block (area between characters {and})

Note: ES6 allows arbitrary nesting of block-level scopes

{{{{{{let text = 'Hello World! '}}}}}}
Copy the code

Because of the block-level scope, then we have the possibility to move on.

1. Block level declaration

Block-level declarations are used to declare variables that are not accessible outside the scope of a given block.

Let declaration: used to declare a block-level scope variable

Declared variables have the property of block-level scope

/ / casefunction getValue (condition) {
    if (condition) {
        let value = 'blue';
        returnvalue; } console.log(value) // Error value is not defined} getValue()Copy the code

You cannot use let to declare variables of the same name in the same scope

// whether var,const, orletThe newletVar count = 30;letcount = 40; / / an Identifier'count'Has already been declared // function parameters and those inside the functionletError: Duplicate variable namefunction test(value) {
    let value = 3;
}
test() // Error Identifier'value'Has already been declared // it is ok to rename variables declared in different scopeslet count = 30;
if(true) {
  letcount = 40; // different scope, no error}Copy the code

3. Declare no pre-parsing, no variable promotion, temporary dead zones (TDZ)

The area from the beginning of the block to the declaration of variables is called a temporary dead zone. ES6 explicitly states that if there are let and const commands in the block, the block has a closed scope on the variables declared by those commands from the start, and any use of these variables (assignment, reference, etc.) before the declaration will result in an error.

if(true) { console.log(typeof value); // Error value is not definedlet value = 'blue';
}
Copy the code

Note: TDZ is the area from “block start” to “variable declaration”, the following example does not report an error

Console. log(typeof value); console.log(typeof value); // Print undefined, no errorif(true) {
    let value = 'red';
}
Copy the code

3, const declaration: Declares a constant (such as PI) that cannot be changed once set

Constants declare values that are immutable

Note: An object declared by const is not allowed to change its binding, but it is allowed to change its property values.

const number = 6; number = 5; Assignment to constant variable const obj = {number: 1}; obj.number = 2; Obj = {number: 3}; Assignment to constant variableCopy the code

2. Since the value of a constant cannot be changed after it is declared, it must be assigned when declared

// Const count = 30; // Error Missing Initializerin const declaration
const name;
Copy the code

Declared constants have the property of block-level scope

if(true) { const number = 5; } console.log(number) // The number is not definedCopy the code

4. You cannot declare a variable of the same name using const in the same scope

var message = 'Hello';
letage = 25; // Both statements report an error const message ='Good';
const age = 30;
Copy the code

5. Declare no pre-parsing, no variable promotion, temporary dead zones (TDZ)


Summary: a table

A declarative way Variable ascension scope Whether an initial value is required Repeat definition
var is Function level Don’t need allow
let no block-level Don’t need Don’t allow
const no block-level Need to be Don’t allow

Extension: The variable name, whether declared by var, let, or const, can consist of numbers, letters, underscores, and dollar signs, but cannot start with a number. The dollar sign can go anywhere, even a single dollar sign.

4. Block scoped bindings in loops

Let declaration in loop

// The first contrast // beforefor(var i = 0; i < 5; i++) { // ... Omit some code} console.log(I) // 5 //afterfor(leti = 0; i < 5; i++) { // ... } console.log(I) // I is not defined // second // var funcs = [];for(var i = 0; i < 10; I++) {funcs. Push (() = > {the console. The log (I)})} funcs. ForEach ((ele) = > {ele ()}) / / print 10 times 10 / / after the var funcs = [];for(leti = 0; i < 10; I ++) {funcs.push(() => {console.log(I)})} funcs.foreach ((ele) => {ele()}) // Prints 0 1 2 3 4 5 6 7 8 9Copy the code

Note: It is important to note that the behavior of let declarations within loops is specifically defined in the standard and is not necessarily related to the let non-promotion feature.

Const declaration in a loop

// forThe loop will report an errorfor(const i = 0; i < 1; Assignment to constant variable. // Assignment to constant variablefor- in andforVar object = {a:true,
    b: true,
    c: true
};
for (const key inObject) {// Do not change the key value in the loop, console.log(key)} // Print a, b, cCopy the code

Note that const can be applied to for-in and for-of loops because each iteration does not modify an existing binding, but creates a new one.

5. Evolution of block-level binding best practices

Early ES6

It is generally accepted that let is used instead of var by default and const is used for write-protected variables

ES6 in use

The general default is to use const, and let is used only when you really need to change the value of a variable. Because most variable values should not change after initialization, unexpected variable value changes are the source of many bugs. This allows the code to be immutable in a way that prevents certain errors from occurring.

6. Global variables are progressively decoupled from the properties of top-level objects

The top-level object refers to the Window object in the browser environment and the Global object in Node.

For compatibility, global variables declared by var and function commands are still properties of top-level objects.

var a = 1;
window.a // 1
Copy the code

On the other hand, global variables declared by let, const, and class are not attributes of the top-level object.

The variable declared by the let is not in the Window object, but is a new Script object.

Extension: If you need to access code across frame or Window in the browser, you can still use var to define variables under global objects.

Block level functions

Starting with ECMAScript 6, in strict mode, functions within a block are scoped to that block. Prior to ECMAScript 6, block-level functions were not recommended for use in strict mode.

'use strict';

function f() {
  return 1;
}

{
  function f() {
    return 2;
  }
}

f() === 1; // true// f() === 2 is equal in non-strict modeCopy the code

Note: Do not use block-level functions in non-strict mode, because in non-strict mode, the declaration of functions in a block is strange and compatibility risk

if (shouldDefineZero) {
   function zero() {// DANGER: compatibility risk console.log()"This is zero."); }}Copy the code

In ECMAScript 6, if shouldDefineZero is false, zero is never defined because the block is not executed. That’s what the new standard defines. However, there is a historical legacy that some browsers define zero whether the block executes or not.

In strict mode, all browsers that support ECMAScript 6 handle it the same way: zero is defined only if shouldDefineZero is true, and scoped only within the block.