5

I have tried to execute the below code in Firefox V30.0 Scratchpad:

function do_something() {
  console.log(foo); // ReferenceError
  let foo = 2;
}
do_something();

The expected behavior is that my program should throw Reference Error, because I am accessing a let variable before it's declaration. But, I am not getting the expected behavior, the program got executed and the result is as below

undefined

Can you explain me, why is it behaving so?

Azeez
  • 318
  • 3
  • 14
  • As far as I'm aware, `let` declared variables are still hoisted, the same as `var`, just to the top of their block, not function. – James Thorpe Dec 11 '15 at 10:29
  • @JamesThorpe - The declarations are hoisted but due to the temporal dead zone any attempt to reference them before they are initialised should throw. – James Allardice Dec 11 '15 at 10:30
  • can you run the code in "strict mode" and see if something changes, in my opinion the expected result is to throw... variable hoistment should happen only if you use the var keyword... – Hitmands Dec 11 '15 at 10:31
  • @JamesAllardice Hmm interesting. One wonders why they're hoisted at all then. And does this mean it's a bug in Firefox's implementation? – James Thorpe Dec 11 '15 at 10:31
  • versión issue? http://caniuse.com/#search=let – jolmos Dec 11 '15 at 10:34
  • @JamesThorpe: See [Are variables declared with let or const not hoisted in ES6?](http://stackoverflow.com/q/31219420/1048572). They're hoisted to shadow higher-scope variables that might or might not exist and prevent the exception from happening. – Bergi Dec 11 '15 at 10:35
  • @JamesThorpe I would assume so, yes. Firefox 30 is pretty out of date (I think - I usually use Chrome so I'm don't really keep up with Firefox releases). – James Allardice Dec 11 '15 at 10:35
  • @Bergi Thanks - that explains the obvious reason for doing so! – James Thorpe Dec 11 '15 at 10:36
  • Just been playing with Babel - seems if you don't have it in high compliancy mode, it will also log `undefined` with the code here. – James Thorpe Dec 11 '15 at 10:38
  • Thanks to all of you - and finally the problem is with the browser compatibility as answered by @Bergi – Azeez Dec 11 '15 at 10:55

2 Answers2

6

According to the MDN compatibility table, Firefox does support the temporal dead zone semantics only since v35.

Also you should always make sure to be using strict mode. Some ES6 features are not available in sloppy mode, due to concerns about breaking the legacy web. It should not affect this specific case though, despite Firefox' already long history of let usage.

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

Let variables in ES6 are hoisted to the top of the block where they are declared in. Reference of the variable before its declaration will result in a ReferenceError (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone_and_errors_with_let). Thus you are correct to expect a ReferenceError to happen in this case.

The reason why the ReferenceError isn't happening in this case is because FF 30 does not support the so called "temporal dead zone". A good place to find out if browsers support specific parts of the ES6 spec is Kangax's Ecmascripts compatibility table (https://kangax.github.io/compat-table/es6/#test-let).

Matthisk
  • 1,501
  • 10
  • 20