Are variables declared with let or const hoisted?

前端 未结 6 1004
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-21 04:58

I have been playing with ES6 for a while and I noticed that while variables declared with var are hoisted as expected...

console.log(typeof name         


        
6条回答
  •  清歌不尽
    2020-11-21 05:21

    As per ECMAScript® 2021

    Let and Const Declarations

    • let and const declarations define variables that are scoped to the running execution context's LexicalEnvironment.
    • The variables are created when their containing Environment Record is instantiated but may not be accessed in any way until the variable's LexicalBinding is evaluated.
    • A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer's AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created.
    • If a LexicalBinding in a let declaration does not have an Initializer the variable is assigned the value undefined when the LexicalBinding is evaluated.

    Block Declaration Instantiation

    • When a Block or CaseBlock is evaluated a new declarative Environment Record is created and bindings for each block scoped variable, constant, function, or class declared in the block are instantiated in the Environment Record.
    • No matter how control leaves the Block the LexicalEnvironment is always restored to its former state.

    Top Level Lexically Declared Names

    At the top level of a function, or script, function declarations are treated like var declarations rather than like lexical declarations.

    Conclusion

    • let and const are hoisted but not initialized.

      Referencing the variable in the block before the variable declaration results in a ReferenceError, because the variable is in a "temporal dead zone" from the start of the block until the declaration is processed.

    Examples below make it clear as to how "let" variables behave in a lexical scope/nested-lexical scope.

    Example 1

    var a;
    console.log(a); //undefined
    
    console.log(b); //undefined
    var b;
    
    
    let x;
    console.log(x); //undefined
    
    console.log(y); // Uncaught ReferenceError: y is not defined
    let y; 
    

    The variable 'y' gives a referenceError, that doesn't mean it's not hoisted. The variable is created when the containing environment is instantiated. But it may not be accessed bcz of it being in an inaccessible "temporal dead zone".

    Example 2

    let mylet = 'my value';
     
    (function() {
      //let mylet;
      console.log(mylet); // "my value"
      mylet = 'local value';
    })();
    

    Example 3

    let mylet = 'my value';
     
    (function() {
      let mylet;   
      console.log(mylet); // undefined
      mylet = 'local value';
    })();
    

    In Example 3, the freshly declared "mylet" variable inside the function does not have an Initializer before the log statement, hence the value "undefined".

    Source

    ECMA MDN

提交回复
热议问题