JavaScript Interview Preparation Cheatsheet

JavaScript Interview Preparation Cheatsheet

Scope

Scope in javascript is directly related to the lexical environment, if we first understand the lexical environment it will be very easy for us to understand scope and scope chain, and it will also help us to understand closures also.

Scope
Where you can access the specific variable or function in our code

let's see some examples

1   function getValue(){
2       console.log(b)
3   };
4   var b = 10;
5   getValue(); // output : 10
1   function getValue(){
2       var b = 10;   
3   };
4   console.log(b)  // error  b is not defined
5   getValue();

simply we get the value, but if I declare the variable b inside the function and try to access the variable outside the function, javascript simply throws a reference error `b is not defined, So here's Scope come into a place

There are two aspects of the scope in the case of var b

  1. what is the scope of a variable or
  2. Is variable lies inside the scope of a function

Before going further let's see what is lexical environment

Lexical environment

The lexical environment is the local memory along with the lexical environment of its parent Lexical in general means in a hierarchy or in a sequence. Whenever a new execution context(EC) is created a new lexical environment is created and it is referenced in the local EC in memory space. let's see an example

1  function a(){
2    var b =1
3    c()
4    function c(){
5    }    
6  }
7  a()

From the definition, we can say the function c is lexically inside the function a and function a is lexically inside the global scope this is known as lexical, so when I say the lexical environment of functions c is the local memory of function along with the lexical environment of its parent, in this case, the parent is function a and for function a the lexical environment is the local memory of function a ( local memory means the local execution context memory of a function a ) and the lexical environment of its parent ( parent of function a is a global execution context

let's see some example

function a(){
    function b(){
        var one  = 2
        console.log(one) // 2
    }
    console.log(one)
}
var one = 3
a()
console.log(one)  // 3

Therefore, we can say that javascript will first search in the local memory for a variable inside function b, and if the variable is present, javascript will use it rather than search in the lexical environment of function a In the case of function b the variable is not present inside the local memory of function a so it will try to find it in the lexical environment of its parent

Types of Scope

JavaScript has three different types of scope.

  • Global Scope
  • Function Scope
  • Block scope Let's take a few examples to understand these three different scopes.

Global scope

Variables declared outside of functions or code blocks (curly braces { }) are considered to have a global scope. The outermost scope contains the entire code, and there is only one global scope in the program.

The variables defined in the global scope are named Global Variables and can be accessed and altered in any other scope.

Function Scope / Local Scope

Each and every function creates its own scope. And the variables declared inside that function are only accessible inside that function and any of its nested functions. This is also called Local Scope.

Block Scope

ES6 introduced let and const variables. With that, it introduced the block scope. Block scope means that the variables defined inside a code clock {} can only be used inside it. for example, if a variable declares using const or let inside if else condition or in a for loop the variable can only be accessible inside the block or inside the {} we can not access them outside the {} or outside the block of if-else or loop or any other block.

const one = 1

if (one === 1){
var two = 2
const three = 2
}
console.log(two)   //  2
console.log(three)  // ReferenceError: three is not defined

mFQtgsb.png

In the case of var, we can access them because the var is stored inside the global memory and we can access variables inside the global memory anywhere inside the code

Scope chain

function a(){
    function b(){
        console.log(one) // 2
    }
    console.log(one)
}
var one = 2
a()

The Scope chain is nothing but a chain of lexical environments and their parent references are called the scope chain in the above example we can see that function b first finds the variable in the local scope then it tries to find it in the parent scope and finally in the global scope

javascript is Single-threaded language

Javascript is a single-threaded synchronous scripting language, javascript has one call stack whenever javascript code run global execution context is pushed inside the call stack and javascript code will execute line by line or we can also say that in a single thread synchronously(In other words, one command is processed at a time) in an execution context.

Let's see an example

function sum(a , b){
     alert("In a function")
    return a + b;
}
const a = 1;
const b = 2;
console.log("Before invoking the function")
const result = sum(a,b)
console.log(result)

ezgif.com-gif-maker(6).gif

as you can see above, The execution is stopped for alert so here we can say that javascript is single threaded language

Execution context

Imagine your code is placed inside a box whenever you write JS code. That box is the Execution context, a conceptual environment created by JS for code evaluation and execution.

execution contex.jpg

Execution context has two components, the memory component, and the code component memory component is also called a variable environment in which all the variables and functions are stored in `key: value pairs

And the code component is also called a thread component in which the whole code is executed line by line. all though javascript is a synchronous single-threaded language its means it executes one command at a time,

The execution context is created in two-phase

Memory creation phase

Let's take a look at a simple js code example,


var a = 3;
function square(num){
     var ans =  num*num
    return ans
}
var square0ne = square(a)
var squareTwo = square(5)

In the memory creation phase as soon as the js encounter the variable a JS allocates the memory for variable a and in the memory JS stores a value called undefined

when js encounter the function square, the memory is allocated for a function and the entire function is stored as a value to their in a memory component to their identifier

for variable squareOne and squareTwo JS allocate the memory and stores the undefined to their identifier

NOTE: For all the variable's in the memory creation phase the value is `undefined for the variable identifier

memory component.png

As soon as javascript allocate memory to all variable and function it will go into the next phase called the code execution phase

Code execution phase

Finally in the code execution phase when javascript encounters the variable the actual >value of a variable is stored in a memory to their identifier

In the above example when the js encounter the variable a the actual value of a which is 3 is stored in the memory to their identifier a

now here is the interesting part of the above code example, when js invokes or calls the function one more local execution context is created inside the code component. local execution context is also created in two-phase memory creation and code execution phase

Let's see how it's looks memory component.png

In the above image, we can see that the local execution is created for a function square since the function is invoked for their pointer is on

1  var a = 3;
2  function square(num){
3     var ans =  num*num  
4    return ans
5  } 
6  var squareOne = square(a)  // << pointer
7  var squareTwo = square(5)

In the memory creation phase, the memory is allocated for the sum variable and for property num which is passed as an argument a whose value is equal to 3.

After the memory creation phase, the code execution phase takes place

1  var a = 3;                                                
2  function square(num){  // << pointer   
3     var ans =  num*num  
4    return ans
5  } 
6  var squareOne = square(a)  
7  var squareTwo = square(5)

as you can see that the pointer goes on line 2 now JS, in memory the value of num set to 3 after that the pointer goes on line 3, after the calculation the value of ans is set as 9
after that, the pointer goes on line 4 which returns ans to the global execution context, and the value of ans is set to the squareOne hence the local execution context is removed from the code component of the global execution context

execution contex.jpg

1  var a = 3;                                                
2  function square(num){  
3     var ans =  num*num  
4    return ans
5  } 
6  var squareOne = square(a)  
7  var squareTwo = square(5)  // << pointer

now one more time local execution context is created for function square, After executing the function it will return ans, and the ans will be set as a value for squareTwo in the global execution context

hence all the code is now executed the whole global execution is deleted

Now let's take a look at the call stack for the same javascript code example

The Call Stack

A stack is a data structure that follows the Last in First Out (LIFO) principle. However, the Call Stack is a stack that keeps track of all the execution context created during code execution.

  1. The global execution context is initially added(pushed) on the execution stack by default, in the form of the global() object.
  2. A Function execution context or local execution context is added to the stack when a function is invoked or called.
  3. The Invoked function is executed and removed (popped) from the stack, along with its execution context.

function greeting() { 
   sayHi();
}
function sayHi() {
   return "Hi!";
}
// Invoke the `greeting` function
greeting();

STEP 1: The GEC is created and pushed on the execution stack as the global() object. STEP 2: The greeting() function is invoked and pushed on the stack. STEP 2: The sayHi() function is invoked and pushed on the stack. STEP 3: The sayHi() function is popped off the stack. STEP 3: The greetings() function is popped off the stack.

mFQtgsb.png

hoisting in javascript

You may have encountered this in javascript when you console.log() a var before declaring, instate of getting an error we get a strange value called undefined let's see what's happened behind the seen.

What is hoisting

Hoisting is the process in javascript by which we can access the variables and functions even before we have initialized it without getting any error

let's take some example

1    var one = 2
2    function getValue(){
3        console.log("hello world")
4    }
5    console.log(one)  //  2
6    getValue()  // "hello world"

as you can see in the above javascript example nothing is new to us, we defined and initialize variable one on line 1, and on line 2 we defined a function and call both of them after defining and ve got their respected value

but what happens when we tried to console.log() the variable and invoke the function before defining them let's see

1    console.log(one); 
2    getValue();
3   
4   function getValue(){
5        console.log("hello world")
6    }  
7    var one = 2;

imgone.png

here you can see in the above example var one and function getValue() got hoisted but why the value of var one is undefined and the function return hello world before I explain this, let's see one more example

1    console.log(one); 
2    console.log(getValue);
3   
4   function getValue(){
5        console.log("hello world")
6    }  
7    var one = 2;

imgone.png

so this is the same value for variable one and function getValue stored in a memory creation phase in the memory component of the global execution context, As we tried to access the value before defining javascript simply give the value stored in a memory, But in the case of a function, the whole function is stored in a memory during the memory creation phase as you can see in the above image,

imgone.png

imgone.png

Function declarations and arrow functions are hoisted?

In the case of function declaration and arrow function, we can not invoke the function before the declaration because both types of declaring the function act like a variable and during the memory creation phase, the value of this function is undefined and if we tried to invoke this type of function we will get a type error,

Difference between undefined and not defined

From the above examples, we definitely can say how we got undefined for the var one but in case I tried to access some variable that is not declared or defined in an entire code so javascript throws a reference error: one is not defined Let's see

1    console.log(one); 
2    console.log(getValue);
3   
4   function getValue(){
5        console.log("hello world")
6    }  
7    //var one = 2;

imgone.png

In the next article, we will try to understand how the javascript function works and take a look at the variable Environment,