(Note: All examples using let are also valid for const)

var is available in all versions of JavaScript, while let and const are part of ECMAScript 6 and only available in some newer browsers.

var is scoped to the containing function or the global space, depending when it is declared:

var x = 4; // global scope

function DoThings() {
    var x = 7; // function scope
    console.log(x);
}

console.log(x); // >> 4
DoThings();     // >> 7
console.log(x); // >> 4

That means it “escapes” if statements and all similar block constructs:

var x = 4;
if (true) {
    var x = 7;
}
console.log(x); // >> 7

for (var i = 0; i < 4; i++) {
    var j = 10;
}
console.log(i); // >> 4
console.log(j); // >> 10

By comparison, let is block scoped:

let x = 4;

if (true) {
    let x = 7;
    console.log(x); // >> 7
}

console.log(x); // >> 4

for (let i = 0; i < 4; i++) {
    let j = 10;
}
console.log(i); // >> "ReferenceError: i is not defined"
console.log(j); // >> "ReferenceError: j is not defined"

Note that i and j are only declared in the for loop and are therefore undeclared outside of it.

There are several other crucial differences:

Global variable declaration

In the top scope (outside any functions and blocks), var declarations put an element in the global object. let does not:

var x = 4;
let y = 7;

console.log(this.x); // >> 4
console.log(this.y); // >> undefined

Re-declaration

Declaring a variable twice using var doesn’t produce an error (even though it’s equivalent to declaring it once):

var x = 4;
var x = 7;

With let, this produces an error:

let x = 4;
let x = 7;

TypeError: Identifier x has already been declared

The same is true when y is declared with var: