Javascript  Interview Preparation Cheatsheet

Javascript Interview Preparation Cheatsheet

Scope

Scope refers to the accessibility or visibility of the variables, functions, or objects during the run time. In simple words, it says whether we can use a particular variable, function, or object In the code at a specific location or not.

There are 3 types of Scope in Javascript - 1. Global Scope 2. Block Scope 3. Function Scope.

1. Global Scope

The first type of scope is called global scope. when we create a code in a particular file and it does not belong to any function, we are basically writing the code in the global scope. The variables can be accessed from anywhere in the program. For example.

var greeting = 'Hello World!';
function greet() {
  console.log(greeting);
}
// Prints 'Hello World!'
greet();

2. Local Scope or Function Scope

when we write code in the function body, we are writing code in the function scope. The variables can be accessed from within the function. It can be accessed from the outside. For example:

function greet() {
  var greeting = 'Hello World!';
  console.log(greeting);
}
// Prints 'Hello World!'
greet();
// Uncaught ReferenceError: greeting is not defined
console.log(greeting);

3. Block Scope

In simple terms, block scope means a pair of curly braces such as an if block or a block created by for or while loop. ES6 introduced let and const variables, unlike var variables which can be scoped to the nearest pair of curly braces. For example:

{
  let greeting = 'Hello World!';
  var lang = 'English';
  console.log(greeting); // Prints 'Hello World!'
}
// Prints 'English'
console.log(lang);
// Uncaught ReferenceError: greeting is not defined
console.log(greeting);

Here var variables are used outside the block, that is why var variables are not blocked scoped, they are function scoped, whereas let and const are blocked scoped.

Lexical Scope

Lexical scope means the nested group of functions, the inner functions have access to the variable and other resources of their parent scope. On the other hand, the outer functions don't have the access to the variables that exist inside their child functions.

// Lexical scope no.1
// Create function to create new local scope
function myParentFunction() {
  // Local scope no.1
  const myParentConst = 'I am a local variable.'

  // Try to access local variable myParentConst
  // This works
  console.log(myParentConst)
  // 'I am a local variable.'

  function myChildFunction() {
    // Local scope no.2
    const myChildConst = 'I am a local local variable.'

    // Try to access local variable myChildConst
    // This works
    console.log(myChildConst)
    // 'I am a local local variable.'

    // Try to access local variable myParentConst
    // from the inside of myChildFunction
    // i.e: Try to access content of parent's scope from its child
    // This works
    console.log(myParentConst)
    // 'I am a local variable.'
  }

  // Try to access local variable myChildConst
  // from the outside of myChildFunction
  // i.e: Try to cess content of child's scope from its parent
  // This doesn't work
  console.log(myChildConst)
  // ReferenceError: myChildConst is not defined
}

// Try to access local variable myParentConst
// from the outside of myParentFunction
// This doesn't work
console.log(myParentConst)
// ReferenceError: myParentConst is not defined

Single Threaded

Single-threaded languages can perform only one task at a time. Javascript is single-threaded which means only one statement is executed at a time. It has only one stack. whenever the code runs, the global execution context is pushed inside the call stack and the code is executed one at a time.

A common example of this is the window alert function alert("Hello World")

we can't move forward or interact with the page unless we hit ok or close the alert box.

Call Stack

In simple terms, the call stack is basically a mechanism that records where we are in the program. It keeps track of the multiple function calls. It does the following :

  • When the Javascript engine invokes a function, it pushed the code to the stack and the execution starts.

  • If the currently executed function calls another function, the engine adds the second function to the stack and starts executing it.

  • Once it finishes executing the second function, the engine takes it out from the stack.

  • The control goes back to resume the execution of the first function from the point it left it last time.

  • Once the execution of the first function is over, the engine takes it out of the stack.

  • It is continued the same way until there is nothing to put into the stack.

Untitled-2022-09-11-0755.png

Let us see with an example below :

function f1() {
  // Some code
}
function f2() {
  f1();
}
function f3() {
  f2();
}
f3();

Lets see what happens in the call stack :

Untitled-2022-09-11-fsadfsadf.png

Notice that first f3() gets into the stack, invoking another function, f2(). So now f2() gets inside while f3() remains in the stack. The f2() function invokes f1(). So, time for f1() to go inside the stack with both f2() and f3() remaining inside.

First, f1() finishes executing and comes out of the stack. Right after that f2() finishes, and finally f3(). Everything that happens inside the call stack is sequential.

The call stack has a fixed size depending upon the implementation. if the number of execution contexts exceeds the size of the stack, a stack overflow will occur.

Hoisting

Hoisting is a phenomenon in javascript in which we can access the variables and function even before it is initialized.

Variables declarations are put into memory during the compile phase. It means moving variable declarations to the top of their scope.

This is the core of the Hoisting; when we say variables and function declarations moved to the top of the code. it basically means the variables are registered in the scope, and memory is allocated before the code execution begins because of which it seems as if they are available to use on the top of the code.

Variable Hoisting

In Javascript, variables are initialized with undefined when they are created. We can use variables in code before it is declared or initialized. Below are some examples showing what can happen if you use a variable before it is declared.

  • var hoisting

    Var declarations are hoisted and initialized with undefined.
console.log(foo); // undefined

var foo = 'bar';

console.log(foo); // "bar"

When the interpreter hoists a variable declared with var, it initializes its value to undefined. The first line of code below will output undefined. It is because foo is hoisted and given a default value. If we use an undeclared value it will throw a Reference Error.

console.log(foo); // Uncaught ReferenceError: foo is not defined
  • let and const hoisting

    let and constant declarations are hoisted but are not initialized with undefined. Accessing a let or const variable before it's declared will result in a ReferenceError:
console.log(foo); // Uncaught ReferenceError: Cannot access 'foo' before initialization

let foo = 'bar';  // Same behavior for variables declared with const

Function Hoisting

Similar to how variables are hoisted to the top of the code in variable Hoisting, functions can also be hoisted. The behavior of Javascript where it seems like function declarations have been moved to the top of the code is called Function hoisting. It gives us the advantage that we can use a function before it is declared.

// program to print the text
greet();

function greet() {
    console.log('Hi, there.');
}

In the above program, the function is called before declaring it, and the program prints out the greeting message.

However, when a function is used as an expression, an error occurs because only declarations are hoisted. For example;

// program to print the text
greet();

let greet = function() {
    console.log('Hi, there.');
}

The above program will give a Reference Error. When the execution phase begins, and the first line of the code is encountered, the JS engine sees that the variable greet is being called as a function, hence it throws an error.

Conclusion

Thanks for reading, and I hope this post helped you learn about Scope, Single-threaded, Call Stack and hoisting in JavaScript. Check out my other Articles.