Javascript Interview Cheat Sheet

Javascript Interview Cheat Sheet

Cover the most common topic asked in an interview

·

7 min read

In this blog, we will cover the most common topic asked in javascript's interview in detail. It will help you to understand how things are working internally in javascript.

Topics which we will cover in this article:

  • Scope in Javascript
  • Lexical Environment
  • Scope Chain
  • Call stack
  • Hoisting
  • Javascript is synchronous

So, let's started

Scope in Javascript

The scope basically refers to the availability of variables and functions in the file. for example, you print a variable or call a function that is not available in the file. i.e there is no scope of that variable or function in the file.

In Javascript, there are mainly three types of scope

  • Global scope
  • Local scope
  • Blocked scope

for understanding the scope let's first understand what is a block in Javascript.

{
  //Block
}

Anything you will be written in these curly braces({...}) is only accessible inside this block. But with the help of closure, we can access the internal functions or variables of this block outside the block.

Global scope

When you defined a variable or function outside any block(i.e {...}) or function. then the scope of that variable or function is global. which means that they can be accessed anywhere in the file.

let num = 10;
console.log(num); // num = 10;

function getName(){
   console.log("Gaurav Kumar");  //Gaurav Kumar
}
getName();

In the above code snippet, 'num' variable and 'getName' function are not declared inside any block so they can be accessible/available anywhere or we can use them anywhere in the file.

Note: the global scope is the default for all code running in script mode

Local scope

When you defined the variable and function inside the block({...}), then you can only use that variable or function in that block only. If you will try to access that variable outside the scope then you will get a not-defined error

function number(){
    var a = 10;
    console.log(a); //10

   function sayHello(){
        console.log('Hello Gaurav'); //Hello Gaurav
    }
    sayHello();
}
number();

In the above code snippet, the scope of variable 'a' and function 'sayHello' is local which means they can only be accessible inside the function 'number'.

If we will try to use variable 'a' or calling function 'sayHello' outside the 'number' function then we will get the error message.

Screenshot (560).png

Same for 'sayHello' function

Block scope

When we declared variables with 'let' and 'const' keywords inside the block({...}). then the variable can only be accessible in that block even if they are in the local scope.

function getName(){
  var name = 'Gaurav';

  if(name == 'Gaurav'){
    let gender = 'male';
    console.log(gender); //male
  }
}

getName();

In the above code snippet, the scope of 'gender' variable is only in the 'if' block/statement({...}). If you will try to access the 'gender' variable outside the if statement then you will get the not-defined error message.

Screenshot (561).png

In the above screenshot, we are trying to access the 'gender' variable outside the if statement even though it is in the local scope we cannot access 'gender' variable because of 'let' and 'const' keywords.

Lexical Environment or Lexical Scope

In Javascript, every running function, code block{...}, and the script as a whole have an internal (hidden) associated object known as lexical Environment.

The lexical environment object consists of two parts:

  1. Environment Record: This part stores all the local variables and functions.
  2. A reference to the outer/parent lexical environment.

Note: when the global/local execution context is created. the lexical environment is also created and each context has its own lexical environment.

Let's take an example

function a(){
  let b = 10;
  function c(){
    let d = 20;
  }
  c();
}
a();

When the above code will be run. first, a global context is created (every context has two parts 1. memory and 2. code).

In the memory part, the global functions and variables are put in it, and also the lexical object which refers to its parent will be present in the memory part. In our example function a() is global so, it will add to the local memory of global context.

Call stack.png

Similarly, when the code of function 'a()' will be executed again new context will be created and in this context, it contains its local properties like variables and functions and also the lexical object of its parent.

So, as we have seen the child execution context has its parent information(lexical environment of the parent) then the child can also use the variables and methods of its parent.

This concept is known as the lexical scope in which the child's context can access its parent properties.

Note: the lexical scope of the global execution context will be always null. because it has no parent to refer

Scope Chain

The chain of lexical environment or lexical scope is known as Scope Chain.

Refers to its parent lexical environment ie. global context.png

Call Stack

The call stack is the mechanism to keep track of the function to be executed currently and what function is called from within that function in the script file. when a function is called it will load into the call stack and when the work of that function will be completed it will remove/pop from the call stack. The call stack follows the LIFO(last in first out) rule. It is difficult to understand call stack by definition so, let's take an example.

var a = 10;

function sayHello(){
  console.log('Say Hello');

  function getAge(){
    console.log('Age is 24');
  }
  getAge();
}
sayHello();

How the call stack mechanism is working?

  1. When the above code/js file is running, a global execution context is created in the call stack.

  2. When the code of 'sayHello' function is executed. it will create a new execution context and load it into the call stack.

  3. When the code of 'getAge' function is executed. it will create again a new execution context and load it into the call stack.

  4. And when the execution of 'getAge' function is completed. it will be removed from the call stack

  5. Same for 'sayHello' function and 'global context'.

basically, it is creating a hierarchy in the call stack. see the diagram below.

Execution Context of sayHello() (1).png

Hoisting

It is the concept/phenomena by which you can access variables and function before they initialize & declared without getting the error.

console.log(a); //undefined (It is not an error)

sayHello();  //calling the function

function sayHello(){
  console.log('Say Hello');  //Say Hello
}
var a = 10;

Note: undefined and no-defined are two different things.

undefined means that reference of that variable is present in the code but you are using it before initialization.

And no-defined means that reference of that variable is not present in your code file. for example, you are accessing 'x' variable in the above code snippet, as we know that 'x' variable is not present in the above code snippet so, that why we will getting a no-defined error.

Let's come back to the hoisting concept

As we already know when the script is running. the global execution context is triggered and every execution context is created in two-phase.

  1. Memory allocation phase: In this phase, all variables and functions of that context are scanned and allocated to memory.

  2. Code allocation phase: In this phase, all variables are initialized with the value.

Hoisting follows the two rule

  1. function declarations are scanned and made available.
  2. variable declarations are scanned and made undefined.

So, when the global context was created it scanned all the variables and functions. and for variables, it assigned a default value that is 'undefined'. see the attached screenshot below.

image.png

In the above screenshot, when the global context is scanned. it assigned the default value to variable 'a'.

And for functions, it is scanned and made available. see the attached screenshot below.

image.png

So, that's why we are able to call the function before declaring it because it is available in a global context or global memory.

Javascript is synchronous

Javascript Is always a synchronous and single-threaded programming language which means that one line of code is executed at a time, and the next line of code will not be executed until the previous line of code finishes its work.

But Javascript behaves like asynchronous in some conditions like setTimeout() etc. In that case, it will not wait for setTimout() to finish its work. It directly jumps to the next line of code.

Synchronous Javascript example

var a = 10;
console.log(a);

sayHello();

function sayHello(){
  console.log('Say Hello'); 
}

The output of the above code will be

10
Say Hello

In the above code. first, it will be the print value of a (that is 10) then goes to the function 'sayHello' the print the console message. So, it will execute all the code in a sequence manner.

Asynchronous Javascript example

function sayHello(){
  setTimeout(() => {
     console.log('Set Timeout');
  }, 3000)
  console.log('Say Hello'); 
}
sayHello();

The output of the above code will be

Say Hello
Set Timeout

In the above code, Javascript behaves in an asynchronous manner. it was not waiting to complete the execution of setTimout() function. it jumps to the next line which is a console message and prints 'sayHello' first.