There is a difference in scope.
You should know that any variable "declared" without let
, var
or const
has global scope, applies to all script.
Maybe you know you should always use the var
to make the scope local, ie it is only within the function where it was declared (can be global if it is not within the function).
But this was not enough, it needs to have a block scope. The let
was created, and is available in newer versions of the language precisely to provide this more limited scope.
Examples:
function exemplo() {
console.log(x);
for (var x = 0; x < 5; x++) {
console.log(x);
};
console.log(x);
};
function exemplo2() {
//console.log(x); //daria erro
for (let x = 0; x < 5; x++ ) {
console.log(x);
};
//console.log(x); //daria erro
}
exemplo();
console.log(" ");
exemplo2();
I put in the Github for future reference.
Documentation of let
.
const
can be used in newer versions of the language and equates to let
only it’s a constant.
As it is not any browser that supports these newer commands, they should be avoided.
When possible to use generally, the let
is preferable, the narrower scope is always preferable. Although if you keep your functions as small as you say "good practices" it won’t make so much difference to use one or the other. And indeed sometimes the var
is a hand on the wheel when you need the "live" value after finishing a scope (not that you can’t do with let
also).
There is another reason for the let
be created is to resolve a matter of creating your own references in closures, they couldn’t change the semantics of language into something that already existed, they created something new, so the new semantics would be opt-in. Let’s take this example:
var funcs = [];
for (var i = 0; i < 3; i++) {
funcs[i] = () => console.log("Valor: " + i);
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
Sounds weird, right? The var
leaves the variable alive throughout the function where it is declared (in this case it is up to global, but gives in it), so the capture of a closure takes a reference to that variable which is considered universal for the function. Now let’s see with the let
which makes the scope as small as possible, that is, the variable only exists in the block for
:
var funcs = [];
for (let i = 0; i < 3; i++) {
funcs[i] = () => console.log("Valor: " + i);
}
for (let j = 0; j < 3; j++) {
funcs[j]();
}
So as long as you use Edge, Firefox 44 forwards, Chrome since 49 (41 in strict mode, from 4 to connect manually), Safari 11 and others based on them, prefer the let
. IE 11 accepts the let
, but does not treat the closure correctly. Or wherever it doesn’t work the person is already used to a lot of things going wrong.
Just remember that if you use the let
must use some transpilator that generates code that is more suitable for older versions, or to be absolutely sure that your page will never be accessed by older browsers. Ensuring this, in general, should always prefer the let
. The var
stays to rotate in browsers that you won’t run a Babel or something.
In addition to everything you’ve read about the block scope, Let also lacks the HOISTING behavior that var has, which basically "throws" the variable to the top of the code, even when it was declared further down
– lucas F