Javascript Interview Preparation: Part 1

Javascript Interview Preparation: Part 1

Demystifying var , let and const

var , let and const are the three ways by which we can declare variables in JS .
var was introduced in the intital version of JS but let and const were introduced in the ES6 version of JS .

Definitions

var-Declares a global scoped variable (except when its in a function scope), optionally initializing it to a value.

let-Declares a block-scoped, local variable, optionally initializing it to a value.

const-Declares a block-scoped, read-only named constant.

Scope

Lets try to understand what scopes they offer .
Lets look at var first:

{
    var a = 5;
}
console.log(a);// it will print 5 even though a is accesses outside of the block in which it is declared because
// it is declared with var which gives it GLOBAL scope

If you have Node installed then you can simply create a JS file (lets say part1.js) and then write the code. For executing it , simple run :

node part1.js

When you run the command , you will get to see the result 5 in your terminal . But when it is used in a function , it becomes function scoped .See this example:

function call() {
    var a = 5;
}
call();
console.log(a);//here it will return error "variable not defined"
//since a can't be accessed outside the function scope

For let and const , block scope is offered . Try running the code below:

{
    let b = 5;
}
console.log(b);// you will get an error that "b is not defined"

or this :

{
    const c = 5;
}
console.log(c);// you will get an error that "c is not defined"

Since they are block-scoped , their values can only be accessed after they are intialised inside their block. Try running this and you can get the result 6:

{
    const c = 6;
    console.log(c);//its in the same block and c is also initialised and hence it will work fine
}

Shadowing

Lets discuss how shadowing of variables work when they are declared with different types.

function shadowing(){
    let a = 1;
    if(true)
    {
        let a=2;
        console.log(a);//here "a" refers to the one which is declared in the closest block that
        //is the if block and hence it has shadowed 
    }
    console.log(a);//here it refers to the "a" which is present in the current scope that is the function scope
}

shadowing();

Here you can see that the variable a declared in the inner block overshadows the a declared in the outer block but again its visibility ends when the if block ends . You can run it and see first 2 and then 1 appearing (as expected).

Now you can overshadow var with let but the opposite is illegal shdaowing and won't work.
Like this code will work well:

function shadowing(){
    var a = 1;
    if(true)
    {
        let a=2;
        console.log(a);
    }
    console.log(a);
}

shadowing();

But this is going to return an error identifier 'a' has been already declared .

function shadowing(){
    let a = 1;
    if(true)
    {
        var a=2;
        console.log(a);
    }
    console.log(a);
}

shadowing();

Similarly var can't shadow const . Now lets move to the next topic .

Redeclaration

If we try to redeclare var variables again , it will work but the same can't be said with const or let.

var a;
var a;//this will work
let b;
let b;//it won't work , it will give "Identifier 'b' has already been declared"
//error
const c;
const c;//again won't work , will give error "Missing initialiser"

Initialisation

Variables declared with var and let can be left uninitialised . But variables declared with const need to be initialised in the same line.

var a;//will work
let b;//will work 
const c;//won't work , will give error missing intialiser

In case you simply declare a variable with var or let and leave it uninitialised , them they are undefined (when you will run console.log(a), you will see undefined).

Reinitialisation

Variables declared with let and var can be reinitialised(or updated) but with const can't be reinitialised simply becuase const variable's value is supposed to remain constant.

var a=5;
a=6;//will work
let b=3;
b=10;//will work
const c=5;
c=6;//won't work since value should remain constant

Next we are going towards a very important topic called Hoisting so lets take some deep breath and dive into it .

Hoisting

var-declared variables are hoisted,meaning you can refer to the variable anywhere in its scope, even if its declaration isn't reached yet. You can see var declarations as being "lifted" to the top of its function or global scope. However, if you access a variable before it's declared, the value is always undefined, because only its declaration is hoisted, but not its initialization. Lets see the below code:

console.log(x === undefined); // true
var x = 3;

(function () {
  console.log(x); // undefined
  var x = "local value";
})();

The above code won't return an error stating that the variable x is not defined simply because of hoisting .The above examples will be interpreted the same as:

var x;//this x was global scoped and hence hoisted at the top of the file
console.log(x === undefined); // true
x = 3;

(function () {
  var x;//var is function scoped when it is used in a function and hence 
//hoisted at the starting of function defintion
  console.log(x); // undefined
  x = "local value";
})();

But let and const variables are not hoisted the way var is but the variables are in a temporal dead zone from the the starting of the block until the declaration is processed. While inside the temporal dead zone , the variable has not been initialized with a value, and any attempt to access it will result in a ReferenceError .This is initialized with a value when execution reaches the place in the code where it was declared. If no initial value was specified with the variable declaration, it will be initialized with a value of undefined.

console.log(x); // ReferenceError
const x = 3;

console.log(y); // ReferenceError
let y = 3;

Wrapping up

Hope you were able to understand what was discussed in this blog . This is just part 1 of this series and future blogs will be available soon ! So stay tuned and thank you !