let and const have a temporal dead zone

var declarations are hoisted and initialised to undefined, so reading one before its line is legal and quietly wrong. let and const are hoisted too — the common claim that they are not is inaccurate — but reading one before its declaration throws.

console.log(a);   // undefined
var a = 1;

console.log(b);   // ReferenceError: b is not defined
let b = 1;

That gap between entering the scope and reaching the declaration is the temporal dead zone, and it turns a class of silent bug into an immediate error. The other half is block scoping, which finally fixes the classic loop-variable-in-a-closure trap without an IIFE. Support is partial and inconsistent across browsers right now, and some engines only honour it in strict mode.