3

The ES6 standard comes up with Temporal Dead Zones, making a variable reference not possible in any way until the lexical binding is evaluated. So what does variable creation at the time of lexical environment initialisation mean to

  1. The programmer ?
  2. The Compiler ?

The declaration of a variable using var declaration might mean something to the programmer previously, but now with TDZ in place does javascript start behaving like java for this purpose? Is there any reason other than the way javascript interpreter works that we have hoisting (as a result TDZ) in the first place?

What happens when a lexical binding is encountered later in the code due to order of execution even when the code appears before it lexically?

let abc = f();
let b;
f(){ return b;}

When does traditionally programming languages like java create variables? When the variable declaration is encountered? or when the lexical scope is initialised?

sasidhar
  • 7,523
  • 15
  • 49
  • 75
  • 1
    maybe because of the lot of questions which can generaly be solved by google in most – Vitaliy Terziev Jan 27 '16 at 08:50
  • not really, I tried most of them like When does a language like java create variables and came up empty handed. Most resources TBZ with good explanation but they fail to explain why would we want it in the first place, because now it won't matter if variables are hoisted (only block scoped elements) – sasidhar Jan 27 '16 at 10:57
  • @sasidhar, there are multiple different steps to "creating" a variable. Are you talking about when they are recognized as variables? Are you talking about when their memory address spaces get populated? Many many languages "create" variables in vastly different ways, you have to look how each is treated in the context of the language. – Jay Feb 01 '16 at 22:23
  • i don't think es6 changes much, only clarifies it and applies it to blocks instead of functions when using `let`. look at how coffee script's js output lists all the vars at the top, and imagine that js functions are internally doing the same thing. the var is "visible but empty" until you assign a value to it. – dandavis Feb 03 '16 at 09:08
  • @dandavis I disagree, es6 has significant impact, the TDZ now makes `typeof` validation not possible. The TDZ is a forcing change, if that wasn't the case then it would have been a simple case of functional scope being changed to block scope. – sasidhar Feb 03 '16 at 11:48
  • can you please provide us an example of how `typeof` changes? – dandavis Feb 03 '16 at 19:39

2 Answers2

1

So what does variable creation at the time of lexical environment initialisation mean to the programmer?

Not much. A programmer only intends to use declared and initialised variables.

That the variable is available in the whole scope (from the beginning) only means that mistakes will be caught easier, as the usage of the variable prior to initialisation fails (with an exception) instead of silently being resolved to an outer-scope (global?) variable. It also means that the identifier, regardless where in the scope it is used, always refers to the local variable - which is just what we'd expect from a scope.

So what does variable creation at the time of lexical environment initialisation mean to the Compiler?

That a lexical environment doesn't change its structure during execution. Static resolution of identifiers in a known scope makes compiling possible, and execution faster.

Just as a counterexample, consider this thing:

var x = "global";
var code = "var x = 'local';";
(function() {
     "use sloppy";
     function test() {
         console.log(x); // what do you think does `x` refer to?
     }                   // It's hard to understand as a developer,
                         // now imagine being a compiler that tries to optimise `test`.
     test();
     eval(code);
     test();
}());

What happens when a lexical binding is encountered later in the code due to order of execution even when the code appears before it lexically?

b is used by the call to f() before it's initialised. Accessing it throws a TDZ exception.
You can try it online.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

I have a feeling that the creation of TDZ had to do with it being a very menial step from var, whereas if they were to go with the seemingly more logical approach of not even having the identifier exist, the engine would have had to undergo even more intensive changes. As for the second part of your question in reference to when other languages "create" variables, there are many other important factors to consider that you seem to have left out, such as is the language interpreted vs compiled, as well as there are multiple different steps to "creating" a variable. It acts differently in many different cases, and there is no single answer. In fact, that is one of the big reasons why there are many different languages.

As for your coding question, it would depend on when you're calling your f function, since function declarations are hoisted in javascript. If you are calling it before b is declared, then you are in a TDZ and b cannot be referenced. It will behave very similarly as if you were simply putting the return b wherever this function is called.

Honestly, it seems as if there is some underlying misunderstanding of javascript, and computer languages in general. Javascript is not "behaving" more like java, in fact the new let keyword has very nuanced behavior, such as being able to be block scoped, compared to type/variable declarations in java. I would suggest not trying to think of the changes in ES6 in terms of other languages; javascript is not like a lot of other languages, it will be very difficult to understand the concepts and how you should be programming with javascript if you do.


EDIT:

As for why there is variable and function declaration hoisting, that is easily googlable.

Jay
  • 998
  • 1
  • 10
  • 22