Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

let vs var in javascript [duplicate]

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
like image 940
Krishna Avatar asked Dec 28 '17 06:12

Krishna


People also ask

Is let or VAR better in JavaScript?

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.

Which is faster VAR or let?

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.

What is difference between LET and VAR in JavaScript?

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.

What should I use VAR or let?

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.


2 Answers

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();
like image 193
31piy Avatar answered Oct 20 '22 15:10

31piy


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? :-)

like image 41
Sreenivas Shenoy Avatar answered Oct 20 '22 14:10

Sreenivas Shenoy