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.
My reply here is not javascript-specific.
As a rule of thumb in any language that lets me do so in a semi-easy way I'd say always use const/final/readonly/whatever it is called in your language whenever possible. The reason is simple, it's much easier to reason about code when it is dead obvious what can change and what cannot change. And in addition to this, in many languages you can get tool support that tells you that you are doing something wrong when you accidentially assign to a variable that you've declared as const.
Going back and changing a const to a let is dead simple. And going const by default makes you think twice before doing so. And this is in many cases a good thing.
How many bugs have you seen that involved variables changing unexpectedly? I'd guess a lot. I know that the majority of bugs that I see involve unexpected state changes. You won't get rid of all of these bugs by liberally using const, but you will get rid of a lot of them!
Also, many functional languages have immutable variables where all variables are const by default. Look at Erlang for example, or F#. Coding without assignment works perfectly in these languages and is one of the many reasons why people love functional programming. There is a lot to learn from these languages about managing state in order to become a better programmer.
And it all starts with being extremely liberal with const! ;) It's just two more characters to write compared to let, so go ahead and const
all the things!
Best Answer
In ECMAScript 5,
yield
is a strict-mode "Future Reserved Word":This means that in non-strict code, your concerns are correct: the correctness of the line
var yield = 5;
will differ in non-strict mode between an ES5 and ES6 implementation. However, in strict mode, the line is invariably invalid for both ES5 and ES6. This means that you should use strict mode whenever possible to maximize forward compatibility of your ES5 code.As for why yield was not fully reserved for non-strict code, I assume this was done to bridge compatibility between ES3, which did not include
yield
as a FutureReservedWord (see ES3 section 7.5.3, on page 14). In order to introduceyield
, the commitee had to break compatibility somewhere, either in the 3-to-5 transition or the 5-to-6 transition. However, some reserved words that were included in ES3 were downgraded to strict-mode reserved words in ES5. I do not know the rationale for that decision.