Doug Crockford discusses let
at this point in his talk, "The Better Parts".
The point is, let
avoids a source of misunderstanding, esp. for programmers with expectations set by languages with block-scope. A var
has function scope (it declares a variable that's visible throughout the function) even though it looks like it has block scope.
var
might possibly still be useful in an extreme case like machine-generated code, but I'm stretching hard there.
(const
is also new and has block scope. After let x = {'hi': 'SE'}
you can reassign to x
, while after const y = x
you cannot reassign to y
. That's often preferrable since it keeps something from accidentally changing out from under you. But to be clear, you can still modify the object y.hi = 'SO'
unless you freeze it.)
Realistically, your impression is right on for ES6: Adopt let
and const
. Stop using var
.
(In another performance of "The Better Parts", Doug says why ===
was added rather than fixing the problems of ==
. ==
produces some "surprising" results, so just adopt ===
.)
A Revealing Example
Mozilla Developer Network gives an example where var
does not work as intended. Their example is a realistic one that sets onclick
handlers in a web page. Here's a smaller test case:
var a = [];
(function () {
'use strict';
for (let i = 0; i < 5; ++i) { // *** `let` works as expected ***
a.push( function() {return i;} );
}
} ());
console.log(a.map( function(f) {return f();} ));
// prints [0, 1, 2, 3, 4]
// Start over, but change `let` to `var`.
// prints [5, 5, 5, 5, 5]
var
trips us up because all loop iterations share the same function-scoped i
variable, which has the value 5
after the loop finishes.
Another Telling Example
function f(x) {
let y = 1;
if (x > 0) {
let y = 2; // `let` declares a variable in this block
}
return y;
}
[f(1), f(-1)] // --> [1, 1]
// Start over, but change `let` to `var`.
// --> [2, 1]
let
declares block-scoped variables.
var
confuses us by referring to the same variable throughout the function.