Understanding var and let

Differences at the time of the creation and execution

  1. Creation Step — This step looks for each variable and function declarations in a JavaScript file and creates a memory for that in a global or functional execution context. e.g.
1| console.log(a); // undefined
2| var a = 10;
  1. Creation Step — Similar to creation steps for var, memory is created for let statements too, but in this case, memory is not assigned to undefined by default. Instead, the variable goes into a temporal dead zone(TDZ), which means the variable can not be used before it is declared.
1| console.log(a); // Refernce Error
2| let a = 10;

Differences in variable scopes

var a = 10;
console.log(a); // 10
console.log(window.a); // a
let a = 10;
console.log(a); // 10
console.log(window.a); // undefined
var a = 10;
var a = 20; // works fine
let b = 10;
let b = 20; // Error
function a() {
var b = 10;
if (b > 0) {
var b = 20; // same variables
}
console.log(x); // 20
}
function z() {
var x = 10;
if (x > 0) {
let x = 20; // different variables
}
console.log(x); // 10
}

Closures 2.0

function outer() {
var a = 10;
return function inner() {
return a + 10;
}
}
var inner = outer();
console.log(inner()); // 20
var App = {};(function(){
var loggedInUser = {
name: "John Doe",
email: "john@example.com",
password: "somepassword",
token: "sometoken",
}
function getLoggedInUser() {
var user = { ...loggedInUser };
delete user.password;
return user;
}
function updateToken(token) {
loggedInUser = {...loggedInUser, token};
}
App.auth = {
getLoggedInUser,
updateToken,
}
})()
console.log(App.auth.getLoggedInUser()); // Works Fine
console.log(getLoggedInUser()); // Reference Error
let App = {};{
let loggedInUser = {
name: "John Doe",
email: "john@example.com",
password: "somepassword",
token: "sometoken",
}
let getLoggedInUser = function() {
var user = { ...loggedInUser };
delete user.password;
return user;
}
let updateToken = function(token) {
loggedInUser = {...loggedInUser, token};
}
App.auth = {
getLoggedInUser,
updateToken,
}
}
console.log(App.auth.getLoggedInUser()); // Works Fine
console.log(getLoggedInUser()); // Reference Error

The Famous Interview Question

for(var i=0; i<3; i++) {
setTimeout(() => console.log(i), 1000);
}
> 3 not 0
> 3 not 1
> 3 not 2
  • Since var i is not a block scoped variable, i will be created in global scope, if you print window.i you will get 3(which is expected).
  • Since the inner function which is passed as a callback in setTimeout, with every loop a new callback is registered and is lexically binded to i variable which has been declared in global context.
  • Since all three callbacks are binded to same window.i lexically, which is 3, when callbacks are called. Everytime 3 is printed.
for(let i=0; i<3; i++) {
setTimeout(() => console.log(i), 1000);
}
// Output
> 0
> 1
> 2
  • With each loop, a new block is created and let i created for each block.
  • Now inside this block, the callback is lixically binded to let i, which would be 0, 1, and 2.
  • Therefore callbacks run, we get 0, 1, and 2.
for(let i=0; i<3; i++) {
(function(a){
setTimeout(() => console.log(a), 1000);
})(i)
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store