How does JS variable override work?

This code works great:

const a = 1;
{
  const b = a; // let use "a" in a sub-scope
}
{
  const a = 2; // let override "a" in another sub-scope
}

      

... but this code doesn't work with a is not defined

on line 3:

const a = 1;
{
  const b = a; // let use "a" in a sub-scope <<< CRASH!! >>>
  const a = 2; // let override "a" in the same sub-scope
}

      

I've tested this on node 7.7.4

. This can only be related to V8, I am curious how Firefox handles this.

Does this have to do with how the variable declaration is defined in the JS spec? const/let

are not being lifted, but "something" (some metadata?) still seems to be lifted, otherwise we wouldn't have a problem.

+3


source to share


2 answers


Boost refers to the concept that variable declarations are hoisted to the top of the variable scope.

More precisely, this is a side effect of the fact that JavaScript builds the runtime in two passes.

The first pass sets up all function and variable declarations. At this stage, variables are declared but not defined, function declarations are declared and defined (these are function declarations: function fnName(){...}

not function function expressions :) var fnName = function (){...}

.

The second pass then executes the code with available declared functions and variables (which are currently unassigned and therefore undefined).



var

is the scope, not the scope. Although let

it is const

possible to declare block-bound variables, the code is generated using two execution passes. The difference is that the block scope must be counted in the first pass within their own scope (block scope or otherwise).

To illustrate this point, consider the second snippet.

The code throws an error in the second case, because after the first pass it can be rewritten as:

// const 'a' declared in this outer scope
const a:
a = 1; 

{ 
  // separate const 'a' declared in this block scope
  // Declarations still hoisted for this block scope
  const b, a
  b = a; // a undefined here
  a = 2;
}

      

+2


source


This follows the ES6 specification for variable declarations using let

and const

. They are both block areas.
The time until the announcement within the area is a temporary dead zone . According to the docs:

In ECMAScript 2015, let's hoist the variable up to the top of the block. However, referring to a variable in a block before declaring the variable results in a ReferenceError being used. The variable is in a "temporary dead zone" from the start of the block until the declaration is processed.



As @Bergi said, this is the time until the actual announcement.

+1


source







All Articles