let / const declarations do hoist, but they throw errors when accessed before being initialized (instead of returning undefined as var would)
let x = 'outer scope';
console.log(x); // => outer scope
(function() {
console.log(x); // => ReferenceError (let is hoisted, but doesn't allow accessing)
console.log(y); // => undefined (var is hoisted and allows accessing)
// here we have a Temporal Dead Zone
let x = 'inner scope var';
var y = 'inner scope var';
}());
Any trying to access variable in TDZ (get or set) throws an error.
Problem - checking for undefined in TDZ
(function() {
console.log(typeof something); // => 'undefined' it's ok
console.log(something === undefined); // => ReferenceError
console.log(typeof bar); // => 'undefined' it's ok
console.log(bar === undefined); // => true variable hoisted and undefined before declaration
console.log(typeof foo); // => ReferenceError
console.log(foo === undefined); // => ReferenceError
let foo = 'let foo';
var bar = 'var bar';
}());
TDZ can be optionally correctly handled in babel.js with es6.spec.blockScoping
option.
source: http://babeljs.io/docs/advanced/transformers/#optional
sources:
http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified/
https://leanpub.com/exploring-es6/read
http://es-discourse.com/t/why-typeof-is-no-longer-safe/15/14