the murmurous sea

JS ES6: Hoisting, Temporal dead zone 본문

#dev/개념정리

JS ES6: Hoisting, Temporal dead zone

lunacer 2020. 6. 3. 18:20

The study started from: I can't hoist const function...?! Why...?

A. Declaring Variables

 

www.youtube.com/watch?v=dzEieWaOJE0&t=5s

www.youtube.com/watch?v=j-9_15QBW2s


B. Temporal Dead Zone


It's because of

: Unlike variables declared with var, which will start with the value undefined, let variables are not initialized until their definition is evaluated.
: Accessing the variable before the initialization results in a ReferenceError.
: The variable is in a "temporal dead zone" from the start of the block until the initialization is processed.

console.log(typeof undeclaredVariable); // prints out 'undefined'

console.log(typeof i); // results in a 'ReferenceError'
let i = 10;

 

check these pages.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone

dmitripavlutin.com/javascript-variables-and-temporal-dead-zone/

 

Another example of...
temporal dead zone combined with lexical scoping

1. ReferenceError
Due to lexical scoping, the identifier foo inside the expression (foo + 55) evaluates to the if block's foo, and not the overlying variable foo with the value of 33.
In the same line, the if block's foo has already been created in the lexical environment, but has not yet reached (and terminated) its initialization (which is part of the statement itself).
The if block's foo is still in the temporal dead zone.

function test(){
   var foo = 33;
   if(foo) {
      let foo = (foo + 55); // ReferenceError
   }
}
test();


2. ReferenceError
This phenomenon may confuse you in a situation like the following. The instruction let n of n.a is already inside the private scope of the for loop's block. So, the identifier n.a is resolved to the property 'a' of the 'n' object located in the first part of the instruction itself (let n).
This is still in the temporal dead zone as its declaration statement has not been reached and terminated.

function go(n) {
  // n here is defined!
  console.log(n); // Object {a: [1,2,3]}

  for (let n of n.a) { // ReferenceError
    console.log(n);
  }
}

go({a: [1, 2, 3]});

 

3. scoping of var and let/const

var a = 1;
var b = 2;

if (a === 1) {
  var a = 11; // the scope is global
  let b = 22; // the scope is inside the if-block

  console.log(a);  // 11
  console.log(b);  // 22
} 

console.log(a); // 11
console.log(b); // 2

 

C. About Hoist in function

Calling the function actually performs the specified actions with the indicated parameters. 
: Functions must be in scope when they are called, but the function declaration can be hoisted.

: The scope of a function is the function in which it is declared (or the entire program, if it is declared at the top level).

 

This works only when defining the function using the above syntax (i.e. function funcName(){}). 
This means that function hoisting only works with function declarations - not with function expressions.

=> check this article: Function Declarations vs. Function Expressions

=> it's the reason that the arrow function doesn't work. It's a function expression too.
     : An arrow function expression is a syntactically compact alternative to a regular function expression,

 

[The code below will not work]

console.log(square)    // square is hoisted with an initial value undefined.
console.log(square(5)) // Uncaught TypeError: square is not a function
const square = function(n) { 
  return n * n; 
}

 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions

 

 

'#dev > 개념정리' 카테고리의 다른 글

JS ES6: Array.from()  (0) 2020.06.05
Event: keydown, keypress, keyup  (0) 2020.06.05
JS: about Event  (0) 2020.06.03
JS: EventTarget.addEventListener() (empty)  (0) 2020.06.03
JS ES6: Functions hoisting check  (0) 2020.06.03
Comments