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.