Body-level inner function declarations interaction with the let "temporal dead zone"

Allen Wirfs-Brock allen at wirfs-brock.com
Sat Jul 19 17:31:24 PDT 2014


On Jul 18, 2014, at 5:34 PM, Shu-yu Guo wrote:

> Hi all,
> 
> Am I correct in understanding that body-level inner functions hoist both declaration *and* initialization to the top of the outer function?

correct.
> 
> That is, given the following snippet:
> 
> Listing 1
> ---------
> function outer() {
>  let x;
>  function inner() {
>    x = 2;
>  }
> }
> 
> Is it equivalent to the following?

yes, for the purpose of your question. Using a var has some other implications that are not relevant to your question.

> 
> Listing 2
> ---------
> function outer() {
>  var inner = function inner() {
>    x = 2;
>  };
>  let x;
> }
> 
> If so, that means in inner functions, all free uses of let-declared variables from outer lexical scopes are in the ES6 "temporal dead zone". More problematically, it means that there is no-easy-to-compute dominance relation (i.e., at parse time) to omit the dead zone checks for any upvar uses of let bindings, even though textually, listing 1 looks like the initialization dominates all uses.

You should be able to eliminate the TDZ checks in inner if all references to inner are dominated by initializing declarations of all upvars referenced from inner.

For example:

Listing 3
---------
function outer() {
 let x;
 function inner() {
   x = 2;  // TDZ check could be eliminated because x is initialized before any reference is made to inner
 }
 inner();  //the initializing let x dominates this reference.
}

Listing 4
---------
function outer() {
 foo(inner);   //x not yet initialized
 let x;
 function inner() {
   x = 2;  // TDZ necessary because a reference to inner dominates the initializing declaration of x
 }
}

Allen


More information about the es-discuss mailing list