JavaScript Interview Preparation CheatSheet

JavaScript Interview Preparation CheatSheet

Topics:

  1. Scope (Global, Local, Block, Lexical Environment, Scope chaining)
  2. Single Thread
  3. Call Stack
  4. Hoisting

Scope:

A lot of (JavaScript) developers talks about “the scope”, but what is it? Scope tells us about the reach of a particular variable in the JavaScript code. If a variable is not in the current scope, it will not be available for use. Let's assume a variable "b". It is very important to know what a scope is and what you can do with it, I would love to make it clearer for you.

There are two aspect of Scope:

  1. What is the Scope of variable "b".
  2. Is variable "b" inside the scope of a function.

Both the aspect of Scope are same.

JavaScript contain following Scopes:

Global scope

Let’s start with the Global scope. From the first moment, you start typing JavaScript code, your in the Global scope. The Global scope is accessible from any place. The Global scope is accessible from any place, as in the below example it is showing how variable b can be accessed in any part of the code. So variable b is a global variable

var b = 10;

function scopeTest(){
  console.log(b);  //10
}

scopeTest();
console.log(b);  //10

Local scope / Function scope

In contrast to global variables, locally scoped ones are only visible within the function they are declared. Each function written in JavaScript creates a new local scope and every variable declared in this scope is a local variable. That means that variables with the same name can be used in different functions. However, any effort to reference a local variable outside its scope will result in a Reference Error:

function scopeTest(){
  var b = 10;
  console.log(b);  //10
}

scopeTest();
console.log(b);  //ReferenceError: b is not defined

Block scope

we have seen variable b defined with the var keyword. Var can declare a variable either in the global or local scope but Var declared in block scope is accessible in global scope also.

The main difference between the local scope and block scope is that the block statements (e.g. if conditions or for loops), don't create a new scope. So the var keyword will not have an effect, because the variables are still in the same scope.

function scopeTest(){
    var b = 10;
    console.log(b);  //10
  }

// block 
{
    var b = 101;
}

function scopeTest1(){
    console.log(`inside scopeTest1 ${b}`);  //inside scopeTest1 101
}

  scopeTest();

  console.log(b); 

  scopeTest1();  //10

ES6 introduced block scope by using the let and const keywords. These two keywords are scoped within the block which are defined.

// block statement 
{
    var b = 101;
    let c = 201;
    const d = 301;
    console.log(`Inside block scope: ${b}`);  //Inside block scope: 101
    console.log(`Inside block scope: ${c}`);  //Inside block scope: 201
    console.log(`Inside block scope: ${d}`); //Inside block scope: 301
}

console.log(`Outer: ${b}`);  // Outer: 101
console.log(`Outer: ${c}`);  //ReferenceError: c is not defined
console.log(`Outer: ${d}`);  //ReferenceError: d is not defined
  • Global variables last as long as the application is running.
  • Local variables last as long as a function is running.
  • Block statements don't create a new scope and the block scope does not apply to var
    keyword.
  • Const and Let can define scope to block statements.

This was scope in JavaScript, as we are now familiar with scope there is another concept called Lexical Environment.

Lexical Environment:-

  • Scope is directly dependent of Lexical Environment

Lexical Environment Diagram:

Lexical_Environment_image.png

What does Lexical mean?

Lexical- means hierarchy or sequence

What is Lexical Environment?

Whenever a Execution Context is created a Lexical Environment is also created. So the lexical environment is the local memory along with the lexical environment of its parent.

So in the above Example,

function inner() is lexically seating inside function outer() and function outer() is lexically seating inside global scope.

Scope_Chain_image.png

In the above example, we will see how lexical environment works

So this part is reference to the lexical environment of outer() and what is the lexical environment of outer is its memory space + the lexical environment of global scope.

Single Thread

JavaScript is a Synchronous Single-threaded language.

Single-threaded means JavaScript can only execute one command at a time.

Synchronous Single Threaded means it will execute line by line, once the first command is fully executed, then it will go to other command. which means it has only one call stack that is used to execute the program.

Call Stack

What is Call Stack?

The call stack is a Last-In, First-Out (LIFO) data structure containing the address at which execution will resume. Let’s understand the call stack by a simple example.

Single-threaded-image.png

When we step into a function, we put something on to the stack, if we return from a function, we pop off the top of the stack that’s all the stack can do. Let’s run this code line by line and check how it exactly works.

Step 1

If you run this file, it will first scan through the whole program and a global execution context is pushed onto the call stack and line by line it will get executed.

Step 2

Once the global execution context is getting executed, we have our outer function which will get on to the stack and finally within the outer function we have a inner function. Which will get on to the stack when called.

Step 3

After all these function callings, now we get a return statement.

Step 4

Now we got the result of the return statement from the “inner” function. So we remove it also from the stack. Now the scope is with the "outer" .Now finally after completing all the rituals and steps of the program “Global Execution Context” will be pop.

So that's how to call stack works.

Hoisting

One of the unique behavior of JavaScript is variable and function hoisting, hoisting enables us to use variable or function before it is been declared.

Hosting is a phenomena in JavaScript by which we can access the variable and functions even before you have initialized.

We will see various examples below that will help us better understand the Variable and function hoisting behavior of JavaScript.

Variable Hoisting :

name = ‘aditya’
console.log(name);
var name;

output: aditya

Even though we have initialized the name variable before we have declared it, our program displays the output as aditya.

Let us see what happens if we declare and initialize the variable after console.

console.log(name);
var name = ‘aditya’

output: undefined

Here we get the output as undefined, because just the declarations are hoisted and not the initialization

Function Hoisiting

Same as variable declarations are hoisted and moved to the top, functions that are declared also get hoisted, see example below:

sayHello();
function sayHello() {
console.log( ‘Hi there, nice to meet you !!’);
}

Output: Hi there, nice to meet you !!

We have called sayHello() function before it’s declaration and get the desired output due to hoisting.

However if we use functions as an expression or Arrow function it will give TypeError: sayHello is not a function. Because sayHello is not a function its just a variable.

Hoisting is the default behavior of JavaScript that enable us to access variables and functions before their declaration.

I hope this article helped you understand some of the core topics of JavaScript, if you liked this article share this article. Thank You