I understand that let has block scope and var has functional scope. But I do not understand in this case, how using let will solve the problem
const arr = [1,2,3,4];
for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(arr[i])
}, 1000);
} // Prints undefined 5 times
const arr = [1,2,3,4];
for (let i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(arr[i])
}, 1000);
} // Prints all the values correctly
As a general rule, you should always declare variables with const, if you realize that the value of the variable needs to change, go back and change it to let. Use let when you know that the value of a variable will change. Use const for every other variable. Do not use var.
In terms of performance comparison, var is faster and let is slower inside the loops while running or executing the code. Re-declaring var declared a variable in the same function or scope gives rise to Syntax Error whereas let declared variable cannot be redeclared.
The main difference between let and var is that scope of a variable defined with let is limited to the block in which it is declared while variable declared with var has the global scope. So we can say that var is rather a keyword which defines a variable globally regardless of block scope.
The color of first heading is stored in a var and the second one is declared by using let. Both of them are then accessed outside the function block. Var will work but the variable declared using let will show an error because let is block scoped.
This is all related to the scope of the variable. Let's try to wrap both the pieces into functions, and observe the output:
function test() {
// `i` will be declared here, making it a non-for-loop scoped variable
const arr = [1, 2, 3, 4];
for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(arr[i])
}, 1000);
} // Prints undefined 5 times
}
test();
So in the first case, i
will be hoisted, and because of the asynchronous nature of setTimeout
, i
will immediately become 4 as the loop ends without waiting. This will make arr[i]
to point to an undefined
element in the array.
In the second case, i
is not hoisted, and has scoped access to each iteration of the loop, making i
accurately available to console.log
statement. Thus the results are as per the expectations:
function test() {
const arr = [1, 2, 3, 4];
for (let i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(arr[i])
}, 1000);
} // Prints all the values correctly
}
test();
First of all, the output will be four times and not five times(as mentioned in your comment). I pasted your code in Babel REPL and this is what I got,
"use strict";
var arr = [1, 2, 3, 4];
var _loop = function _loop(i) {
setTimeout(function () {
console.log(arr[i]);
}, 1000);
};
for (var i = 0; i < arr.length; i++) {
_loop(i);
}
Do you see how let works internally now? :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With