JavaScript Interview Preparation Cheat-Sheet

JavaScript Interview Preparation Cheat-Sheet

Scope

Values and expressions that are "visible" or that can be referred to inside the current context of execution are said to be within the scope. A variable or expression won't be usable if it's not in the current scope. In a hierarchy, scopes can also be layered so that children can access parents but not vice versa. Scope determines the accessibility (visibility) of variables.

Block Scope

JavaScript only had Global Scope and Function Scope prior to ES6 (2015).Let and const are two crucial new JavaScript keywords that were added with ES6.Block Scope in JavaScript is provided by these two keywords.A block's defined variables cannot be accessed from outside of it.

{
  let x = 2;
}
// x can NOT be used here
// program showing block scope
// global variable
let a = 'Hello';

function greet() {

    // local variable
    let b = 'World';

    console.log(a + ' ' + b);

    if (b == 'World') {

        // block-scoped variable
        let c = 'hello';

        console.log(a + ' ' + b + ' ' + c);
    }

    // variable c cannot be accessed here
    console.log(a + ' ' + b + ' ' + c);
}

greet();

Output

Hello World
Hello World hello
Uncaught ReferenceError: c is not defined

Variables declared with the var keyword can NOT have block scope.Variables declared inside a { } block can be accessed from outside the block.

Local Scope

Variables declared within a JavaScript function, become LOCAL to the function.

// code here can NOT use carName

function myFunction() {
  let carName = "Volvo";
  // code here CAN use carName
}

// code here can NOT use carName
// program showing local scope of a variable
let a = "hello";

function greet() {
    let b = "World"
    console.log(a + b);
}

greet();
console.log(a + b); // error

Output

helloWorld
Uncaught ReferenceError: b is not defined

Variables with the same name can be used in separate functions because local variables can only be utilised within of their respective routines. When a function begins, local variables are generated, and they are removed when the function is finished.

Function Scope

A new scope is created by each function in JavaScript. A function's declared variables cannot be accessed or seen from outside the function. When declared inside a function, variables declared using var, let, and const are quite similar to one another.

function myFunction() {
  const carName = "Volvo";   // Function Scope
}

Global Scope

Globally declared variables have a scope that extends outside of any function. In a JavaScript programme, global variables can be accessed from anywhere. When defined outside of a block, variables declared using var, let, and const are quite similar to one another.

var x = 2;       // Global scope

Lexical scope

A function scope's ability to access variables from the parent scope is known as lexical scope. We refer to the parent function's lexical binding of the child function as "lexically binding." The alleged hierarchy that JavaScript's lexical scope upholds is depicted in the diagram below.

Screenshot 2022-09-10 170305.png

As seen in the aforementioned example, the functions can access all variables from their parent scopes up to the global scope thanks to lexical scope, but no scope is able to access any variables from any functions declared inside it.

var a = 10; // variable a assigned to 10

var func = function (){ // outermost function
    var b = 20;
    console.log("a and b is accessible (outer):", a, b);
    var innerFunc= function (){ // innermost function
        var c = 30;
        console.log("a and b and c is accessible (innner):", a, b, c);
    }
    innerFunc();
    return;
}
func(); // invoke function func 
console.log("only a is accessible (global):", a);

Since variable an is in the global scope in the code above, all function scopes can access its value. Variable b is currently inaccessible from outside the function that has been allocated to func. This is due to the variable's local scope for the function the variable func is allocated to. Additionally, the function that is assigned to the innerFunc variable has access to variables b and c. This is due to the fact that the outer functions lexically bind the inner functions.

NOTE: To identify variables accessible in a specific scope, JavaScript employs a scope chain. When a variable is mentioned, JavaScript first searches the current scope before moving on to parent scopes and finally the global scope. The scope chain is the collection of traversed scopes.

Single Thread

  • Javascript is a single threaded language that can be non-blocking. Single threaded means it has only one call stack. Whatever is on the top of the call stack is run first.

  • A single call stack and memory heap define a single-thread language. It implies that only one process is carried out at once.

  • A stack is a continuous area of memory that allots local context for each function that is executed.

  • A heap is a significantly larger area that houses everything that is dynamically allocated.

  • A data structure called a call stack basically keeps track of where we are in a programme.

Call Stack

The call stack is a tool that the JavaScript engine employs to handle execution contexts. Although the JS call stack's operation is carried out internally, we shall comprehend it here.

We will talk about the JavaScript call stack and how it functions in this part. We'll also talk about an illustration to help us comprehend the idea better.

Javascript Call Stack: What Is It?

The JavaScript engine runs the global execution context and the function execution context in JavaScript. The JS engine employs the call stack to manage these execution environments. The JS call stack, then, is a data structure that records information about the functions that are called and performed. As a result, when a user calls a function to be executed, the specified function is added to or pushed up the call stack, and when a user exits a function, the function is removed from the call stack. Call stack is a standard stack data structure that adheres to the LIFO stack order principle (Last In First Out).

Let's write a simple code and track what's happening on the call stack.

stack.gif

The functions are added to the stack, used, and then destroyed, as you can see. It follows the so-called Last In, First Out method. A stack frame is the name given to each element in the call stack.

For reading error stack traces, knowledge of the call stack is helpful. Though the order of code execution is bottom-up, in most cases the precise cause of the issue is in the first line at the top.

Execution of JavaScript code.

Before delving into the idea of hoisting, let's first have a look at an example of how javascript will execute code in the background.

var a = 2;
var b = 4;

var sum = a + b;

console.log(sum);

In this straightforward example, two variables, a and b, are initialised and stored with values of 2 and 4, respectively. The value of a plus b is then added and stored in the sum variable. Let's examine how the code in JavaScript runs in the browser.

A context for the code's execution will be created by the JS when it first gets it. Execution context will initially go over every line of code and allot memory to every variable and function. JavaScript keeps the complete function code reference in memory for functions and stores undefined for variables, notably var.

Screenshot 2022-09-10 171850.png

Visual Exceution Context

eiz3o1fe8lx4okxtmi27.webp

Hoisting

1_KiqWbbwm7tlcx_e3iAQwMw.gif

Another baffling Javascript concept is hoisting, which is falsely represented as the magical elevation of variable and function declarations to the top of their scope so they can be utilised before being declared. The Javascript engines create the global execution context for top level codes—codes that are not inside a function—and the execution context when a piece of code is performed. The execution context contains:

  • Variable environments
  • Scope chain
  • This keyword.

The following components are all formed during the creation phase, and variables and function declarations are relocated to the top of their scope during the formation of the variable environment. Hoisting is the process of moving a variable or function declaration to the top of its scope so that it can be accessed before being declared in the code. It is crucial to remember that not all variable types—which we shall examine in this article—can be hoisted.How hoisting works with:

  • Function declarations
  • Var variables
  • Let and const variables
  • Function expressions and arrow functions

Hoisting with function declarations:

You can use function declarations before declaring them in the code, which is one advantage they have over function expressions. This indicates that hoisting is effective with them, but why? Function declarations are actually hoisted, and the actual function is assigned as the variable's initial value. This indicates that the reason they are used before being declared in the code is because variables are stored in the variable environment prior to execution.

Hoisting with var variables:

However, they are raised in a different manner. Undefined is returned if we attempt to access a var variable before it has been declared in the code. This strange issue is why it is advisable to use the const and let keywords when creating variables rather than var because var often results in coding errors.

Hoisting with let and const variables:

They are not hoisted. Their value is initialised, making it appear as though there is no hoisting at all because there is no value to work with. As an alternative, we state that the variables are positioned in a TDZ-temporal dead zone, making it impossible to access the variable between the scope's start and the variable's declaration.

Temporal Dead Zone

This area exists prior to a variable being declared. If we attempt to access this variable in the TDZ, we will encounter a reference error as if the variables were nonexistent. Cannot access 'variable' before initialization due to a reference problem.

Reasons for TDZ

  • It facilitates the detection of bug errors.
  • The purpose of TDZ is to stop you from accessing variables before declaration because doing so is a bad habit that should be avoided.

Hoisting with function expressions and arrows

Depending on the keywords that were employed in their creation. This is because these functions, which are only variables, act similarly to variables while being hoisted. This indicates that a function expression or arrow function generated using var is raised to undefined, whereas one made with let or const will result in an error due to TDZ unless accessed after declaration. Conclusion: It is bad practise to access variables before declaration; instead, list all of your variables at the front of your code to avoid errors.