preface

  • Reading this article will take about 10 minutes \color{red}{10 minutes}
  • This article tells about:
      1. JS declaration of variables and functions
      1. LET vs. CONST
      1. Difference between LET and VAR
          1. There is no variable promotion in LET
          1. LET does not allow duplicate declarations
          1. Temporary dead zone
          1. LET generates block-level scope
      1. Many cases and detailed explanation of block-level scope
  • If you have any questions, please leave a message to me. I will reply when I see it. If I can’t solve it, we can also discuss and learn together. If you think there is any mistake, please kindly comment and correct me. Thank you very much. I hope to learn and make progress together with you in the future.
  • The next article will be updated as soon as possible, and the already written article will be modified intermittently in the future as understanding deepens or illustrations are added.
  • If you find this article helpful, please give it a thumbs-up. Thank you!
  • Welcome to reprint, please indicate the source.

VAR, LET, CONST

JS declaration of variables and functions

  • “Traditional”
    • var
    • [function XXX (){}]
    • Var XXX = function(){}
  • 【 ES6 】
    • let
    • const
    • Let XXX = ()=>{};
    • 【import XXX from ‘XXX ‘】

LET vs. CONST

  • LET createsvariable, but its pointer pointer can be changed at will.
  • CONST createsvariable, except that once his pointer is fixed, it cannot be changed.2. Looks like but is not constant.
    • Variables created by const are not allowed to be modified ~~

Difference between LET and VAR

  • 1. There is no variable promotion in LET

    • During code execution, use a variable before let defines it,The browser will first look to see if there is a let declaration in the code below.
      • Error: can’t use this variable before let declaration
      • Otherwise, an error is reported.

  • 2. LET does not allow repeated declarations

    • It is not allowed to use LET to declare the same variable repeatedly in the same context.And,The detection error occurs during the lexical parsing (AST lexical parsing tree) phase, not during code execution
      • (AST lexical tree) : split the code into corresponding characters and identify them as objects that can be parsed by the browser. This stage includes scope chain, parameter assignment, this pointing, variable promotion, etc.)

  • 3. Temporary dead zones

    • A browser bug that detects an undeclared variable will not report an error. The result is “undefined”

  • 4. LET generates block-level scope

  • [ES6] block-level scope

  • In ES6, based on let/const/function… Create a variable

  • Let /const/function… is considered a block-level scope if it occurs inside the curly braces of a non-function (non-object).

    • The presence of the FUNCTION keyword in {} creates block-level scope, which was added in newer browsers
  • IF a FUNCTION appears inside the curly braces {} of the FUNCTION/object, then in the global context of the variable promotion phase, this FUNCTION is declared but not defined.

  • Even if both LET/CONST/FUNCTION and VAR are present in braces, the block-level scope does not apply to VAR

    • VAR declarations in block-level scopes define variables that affect the parent context, which already existsDefined by function/var declarationVariables will be modified, and non-existent ones will be created synchronously.
    	/* Block-level context in the loop */
        for(let i = 0; i<5; i++){console.log(i);
        }
        // The braces in the For loop are a block-level scope,
        // This for has its own private context
        When the loop ends, a total of six private context/block-level scopes are generated
        //for{} let () {let ()
    Copy the code
  • Because [new version browser] is compatible with ES3/ES6, inEncounter if (block-level scope)infunctionWhen the function itself is executed, it still has its own private context.

    1. In the variable promotion phase, in EC(G), only function a is declared.Function a is defined in EC(G). Function A is defined in EC(G). Function A is defined in EC(G).

    2. While the code is executing,Enter the private context of the block-level scopeFunction a will be declared and defined.

    3. InThe code execution phase of the private context of this block-level scope, will not process this line of code.

    4. 【 key 】 only inBlock-level scope at global levelOne more layer and there is no mapping… 】 :

    • But the browser doesIn the private context of this block-level scope=== === ==All operations on variable A are mapped to the global copy, in order to be compatible with ES3, and all the operations on variable A after [=== line code] === =, will beThis is just an operation on a in the private context of the block-level scope.
          var a = 0;
          if(true){
              a = 1;
              function a(){};
              a = 21;
              console.log(a);/ / 21
          }
          console.log(a);/ / 1
          // block scoped private context variables are mapped globally when promoted, global a = function;
          // Then the private context code executes, a = 1;
          // all operations on a before function are mapped to global a = 1;
          // Then the private a is equal to the function, the private context variable promotion stage is not repeated, so the effect on the global A is stopped, no more mapping.
          // All subsequent operations on a are performed only on private A
    Copy the code

       {
           function foo(){};
           foo = 1;
       }
       console.log(foo); //=> function foo
       // Only foo is declared in the global context
       // What really makes the global foo = function work is that in the private context of the block-level scope, when the variable is promoted, the private Foo declaration is defined and mapped to the global
       // Foo = 1; Completely private operations are no longer relevant globally.
    Copy the code

        {
            console.log(foo);// function foo [private promoted variable]
            console.log(window.foo);//undefined
            // The previous operation will not be mapped to the global until the last time function foo is run.
            function foo(){};
            foo = 1;
            function foo(){};// Execute this sentence, the following will not be mapped to the global
            console.log(foo);/ / 1
        }
        console.log(foo);/ / 1
        // Only foo is declared in the global context
        // What really makes the global foo = function work is that in the private context of the block-level scope, the private Foo declaration is defined when the variable is promoted (so the processed foo is not processed at execution time).
        // map to global [last count of function foo in private context's variable promotion]
        // Then the private context code executes foo = 1; Before the function statement, map to the global, global a = 1;
        // The effect on global A stops here. After that, the private operation is performed completely, and the global operation is irrelevant.
    Copy the code

        var a = 12;// function a [cross out] //13 [final]
        if(true) {console.log(a);// function A // block-level scoped private context variable promotion, function declaration + definition
            a = 13;
            console.log(a);/ / 13
            function a(){};// previously mapped to the global
            a = 14;
            console.log(a);/ / 14
        }
        console.log(a);//13
        
    Copy the code

  • The advanced

        //EC(G)
        // The variable is promoted
        //VAR X
        / / FUNC = function
        var x = 1;
        function func (x,y = function anonymous1(){x = 2}){
            / / EC (func) private
            
            (func),ec(g)>
            // parameter assignment x=5 y = function anonymous1
            // Variable promotion --
            x = 3;
            y();
                / / EC (anonymous1) private
                // Scope chain 
            (anonymous1),ec(func)>
                // Parameter assignment --
                // Variable promotion --
                //x uses the parent context
            console.log(x);/ / 2
        }
        func(5);
        console.log(x);/ / 1
    Copy the code

    	// Function body braces form block-level context
        //EC(G)
        // The variable is promoted
        //VAR X
        / / FUNC = function
        var x = 1;
        function func(x,y =function anonymous1(){x = 2}){
            / / EC (func) private
            
            (func),ec(g)>
            // parameter assignment x=5 y = function anonymous1
            // Variable promotion --
                
            / / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
            // Find conditions for function braces to form block-level context
            // Create a single private block-level context (use the function body {} as the new block-level context)
            / / EC (Block) private
            // BLOCK level context scope chain 
            (block),ec(func)>
            Var x will pass in the value assigned by the parameter in the function's private context to the declared private variable x = 5
            var x = 3;//EC(Block) change the Block level scope x to 3
            y();// there is no private variable y in EC(Block), look up and execute y in EC(Func)
                / / EC (anonymous1) private
                // Scope chain 
            (anonymous1),ec(func)>
                // Parameter assignment --
                // Variable promotion --
                //x uses the parent context EC(func)
            console.log(x);//3 => But here the output is executed in the block-level context, and the output is x in the block-level context
        }
        func(5);
        console.log(x);/ / 1
    Copy the code

    // Function body braces form block-level context
        //EC(G)
        // The variable is promoted
        //VAR X
        / / FUNC = function
        var x = 1;
        function func(x,y =function anonymous1(){x = 2}){
            / / EC (func) private
            
            (func),ec(g)>
            // parameter assignment x=5 y = function anonymous1
            // Variable promotion --
            
            / / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
            // The condition that the function curly braces form a block-level context is found
            // Create a single private block-level context (use the function body {} as the new block-level context)
            / / EC (Block) private
            // BLOCK level context scope chain 
            (block),ec(func)>
            Var x var y
            // parameter assignment x = 5 y = function anonymous1() passes in the value of parameter assignment from the function private context to the declared private variable
            var x = 3;//EC(Block) change the Block level scope x to 3
            var y = function anonymous2(){x = 4};//EC(Block) change y in the block-level scope to anonymous2
            y();// anonymous2 of EC(Block)
                / / EC (anonymous2) block level
                // Scope chain 
            (anonymous2),ec(block)>
                // Parameter assignment --
                // Variable promotion --
                //x uses the block-level context EC(BLOCK)
                //x = 4
            console.log(x);//4=> Here the output is executed in the block-level context, and the output is x in the block-level context
        }
        func(5);
        console.log(x);/ / 1
    Copy the code

  • Curly braces on the function body also form block-level context in some cases

    • When afunction Both conditions are satisfied, a private block-level context will be formed at the same time as the private context will be formed at the time of its execution. Function execution has two contexts
      1. Tangible parameters are assigned default values
      2. VAR/LET/CONST; VAR/LET/CONST;
        • A FUNCTION generates a block-level context only if the declared name is the same as the name in the parameter.
        • VAR/LET/CONST is generated regardless of whether the parameter and private variable declarations are the same
    • [Newly formed block-level context]the【 Superior context 】is[Function private context]And the parameter assignment from function Private context is passed in to the declared private variable