In the case of reachares, var declaration and reachares are required

  1. In the case of the reactometer, a variable declared in function scope or global scope via the keyword var, no matter where it is actually declared, will be treated as if it were declared at the top of the current scope. That’s the reactometer mechanism
  2. The declaration of the variable is promoted to the top of the function, but the initialization is left in place

Block-level statement

  1. Block-level declarations are used to declare variables that are not accessible outside the scope of the specified block. Block-level scope (lexical scope) exists in:

    • Function of the internal
    • In the block
  2. Let the statement

    The let declaration has the same syntax as var. Replacing var with let limits the scope of a variable to the current block of code and the let declaration is not promoted

  3. Prohibit duplicate statement

    • If an identifier already exists in the scope, then using the let keyword declaration will throw an error
    • A let cannot be used to repeatedly define an existing identifier in the same scope, so it throws an error
    • If another scope is embedded in the current scope, you can declare a variable of the same name in the nested scope with a let without throwing an error. In this case, the variables in the nested scope will override the variables in the current scope
  4. Const statement

    • The const keyword declares a constant, and its value cannot be changed once set, so every variable declared as const must be initialized
    • Const and let declarations are block-level identifiers, so constants are valid only within the current block of code and are destroyed immediately when executed in the outer block.
    • Constant declarations are also not promoted to the top of the scope
    • Like let, const does not support repeated declarations
    • If the value of a variable declared as const is an object, then the value in the object can be modified
    • The const declaration does not allow modification of the binding, but does allow modification of the value
  5. Temporal Dead Zone~TDZ

    Unlike var, variables declared by let and const are not promoted to the top of the scope, and even relatively safe typeof operators can trigger a reference error if they are accessed before declaration

    If (condition){console.log(value)// reference error let value = 'blue'}Copy the code

    Because the console statement throws an error, the let statement that defines and initializes the variable value, which is still in a temporary dead zone, will not execute

    When the JS engine scans the code for variable declarations, it either promotes them to the top of the scope (var) or puts them in a temporary dead zone. Accessing a variable in TDZ will trigger a runtime error, and the variable will be removed from the temporary dead zone only after the variable declaration statement has been executed, and then can be accessed normally

    console.log(typeof value) // undefined
    if(condition){
      let value = 'blue'
    }
    Copy the code

    Access before the let is declared within the block-level scope of the let results in a runtime error

    Outside the block-level scope where the let is located, it does not cause a runtime error, undefined

Block-scoped binding in a loop

  1. Function in a loop

    Dilemma: The var declaration makes it extremely difficult to create function changes in a loop

    var funcs = [] for(var i = 0; i<10; i++){ funcs.push(function(){ console.log(i) }) } funcs.forEach(function(func){ func() })Copy the code

    The number 10 will be printed ten times because the same variable I declared by var in the loop will be called

    Solution: Use the call immediately function expression (IIFE) in the loop to force a copy of the count variable to be generated

    var funcs = [] for(var i = 0; i<10; i++){ funcs.push(function(value){ return function(){ console.log(value) } }(i)) } funcs.forEach(function(func){ func() })Copy the code

    In this case, 0 to 9 is displayed

  2. Let declarations in loops

    Solve the above problems with let declarations

    var funcs = [] for(let i = 0; i<10; i++){ funcs.push(function(){ console.log(i) }) } funcs.forEach(function(func){ func() })Copy the code

    In this case, 0 to 9 is displayed

    Let declarations mimic what IIFE does above to simplify the loop. Each iteration creates a new variable and initializes it with the same value as the one in the previous iteration, so each function created inside the loop gets its own copy of I

  3. Const declaration in a loop

    The behavior of const in a loop is very similar to that of a let, except that when const is used in a loop, the value declared as const cannot be changed

Global block-scope binding

  1. Another difference between lets and const and var is how they behave in the global scope:

    • When var is used in the global scope, it creates a new global variable as the global object (the window object in the browser environment), as shown below

      var RegExp = 'hello'
      console.log(window.RegExp) // hello
      Copy the code

      Global variables declared by var overwrite existing global attributes

    • Using a let or const in the global scope creates a new binding in the global scope, but the binding is not added as a property of the global object. In other words, using a let or const does not overwrite the global variable

      Let the RegExp = 'hello' console. The log (window. The RegExp) / / ƒ RegExp () {} [native code] the console. The log (RegExp) / / 'hello'Copy the code

      Here the let creates a RegExp variable that binds and masks the global, but does not break the global scope

    • If you do not want to create properties for global objects, it is much safer to use let and const

Evolution of block-level binding best practices

By default, using const, and using let only when the variable really needs to change, makes the code somewhat immutable and thus prevents some errors