JavaScript interview preparation cheat sheet

JavaScript interview preparation cheat sheet

Table of contents

No heading

No headings in the article.

First we will discuss about Scope in Java Script.

  • Scope in JS:

    A variable’s scope is the part of a program where it is available for use.

  • JavaScript variables are lexically scoped, meaning that we can determine a variable’s scope from where it is declared in the source code. (This is not entirely true: var variables are not lexically scoped, but we will discuss that shortly.)

Take the following example:

if (true) {
    const foo = "foo";
    console.log(foo); // "foo"
}

The if statement introduces a block scope by using a block statement. We say that foo is block-scoped to the if statement. This means it can only be accessed from within that block.

If we try to access foo outside of the block, we get a ReferenceError because it is out of scope:

if (true) {
    const foo = "foo";
    console.log(foo); // "foo"
}

console.log(foo); // Uncaught ReferenceError: foo is not defined
  • Why java script is single threaded language?

Javascript is a single threaded language. This means it has one call stack and one memory heap. As expected, it executes code in order and must finish executing a piece code before moving onto the next. It's synchronous, but at times that can be harmful. For example, if a function takes awhile to execute or has to wait on something, it freezes everything up in the meanwhile.

A good example of this happening is the window alert function. alert("Hello World")

You can't interact with the webpage at all until you hit OK and dismiss the alert. You're stuck.

Javascript is a synchronous language by default. This means that all the statements and functions execute one after the other in a predefined order. Javascript behaves this way because it has only a single thread of execution. Other languages like Java provide a multi-threaded execution environment, wherein there’s the main thread as well as other threads that can be created in runtime to run tasks in parallel. Hence, asynchronicity is quite simple and straightforward to achieve in these languages.

However, since Javascript provides us only with a single thread of execution, we need to understand how certain functions that seem to be asynchronous, like the setTimeout function, are able to run. But before we do that, let’s have a look at how the single-threaded execution flow works.

  • Single-Threaded Execution Take the example of this simple program
function sayOne() {
    console.log("1");
}

function sayTwo() {
    console.log("2");
}

sayOne();
sayTwo();

Output:-

1 2

In line 1, the program saves a function declaration to a variable ‘sayOne’. Note that it only saves the function declaration but does not call it yet. So, at this point, none of its code is actually run and hence line 2 would not get executed yet. In line 5, it saves another function definition to a variable ‘sayTwo’ (but doesn’t call it yet). In line 9, it calls the function sayOne. At this point, the saved function definition of sayOne is executed, which results in line 2 of the program being executed and the value of “1” being printed onto the console. Similarly, in line10, the program calls the function sayTwo, which leads to line 6 getting executed, which prints the value of “2” onto the console.

The above execution flow seems pretty straightforward and easy to grasp. Javascript executes the program line by line and executes them in that order. However, as you may have seen, the program isn’t truly being executed line by line and there’s some jumping around in the order of execution of lines, due to function calls. We’ll see about it later in this article. Another good thing to note here is that Javascript wouldn’t move on to the next line of execution until the previous line is executed.

  • What is call stack?

Javascript has something called a call stack, to keep track of the order of functions to be executed. The call stack, as the name suggests, is a stack. Hence, items added to this stack will exit out of the stack in a ‘last in, first out’ order.

function sayOne() {
    sayThree();
    console.log("1");
}

function sayTwo() {
    console.log("2");
}

function sayThree() {
    console.log("3");
}

sayOne();
sayTwo();

In the above program, when the program reaches line 14, the Javascript program sees that the function sayOne is to be called. When this happens, it adds function SayOne to the call stack. So, the stack currently looks like this:-

image.png

This function remains in the call stack and is popped out only after its execution is completed. The way Javascript works, it always first executes the function at the top of the stack, then pops it out of the stack and then moves to the next function in the stack. Hence, the program now ‘jumps’ into the execution of the function at the top of the stack, which is the sayOne function. The execution of sayOne starts at line 2, where the program sees that the sayThree function is to be called. So, Javascript adds this function too to the call stack. The updated call stack now looks like this:-

image.png

The program then jumps to the execution of the function at the top of the stack, which is the sayThree function. The code of sayThree function is now run, in which line 11 prints “3” onto the console. The program then sees that it has reached the end of the sayThree function and hence pops it out of the stack. So, the stack now looks like this:-

image.png

Javascript then sees that the sayOne function is at the top of the stack and hence, jumps back to where it left off in its execution. Line 3 prints “1” onto the console. Once more, upon reaching the end of sayOne function, Javascript pops it out of the stack, which then looks like:-

image.png

After seeing that the stack is empty, the Javascript program then jumps back to where it left off in the original execution, which is to line 15, where it sees that sayTwo function is called. As you might have guessed, sayTwo gets added to the stack:-

image.png

Since it’s the topmost function in the stack, the program’s execution jumps to that of sayTwo, where in line 7, the value of “2” is printed on to the console. Upon reaching the end of the function, it is popped off the stack and the call stack is now empty. There are no more lines to run and hence the program terminates.

  • Hoisting In JS:-

In short how we can describe hoisting

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.

this means that no matter where functions and variables are declared, they are moved to the top of their scope regardless of whether their scope is global or local.

Of note however, is the fact that the hoisting mechanism only moves the declaration. The assignments are left in place.

If you’ve ever wondered why you were able to call functions before you wrote them in your code, then read on!

undefined vs ReferenceError Before we begin in earnest, let’s deliberate on a few things.

console.log(typeof variable); // Output: undefined
  • This brings us to our first point of note:

In JavaScript, an undeclared variable is assigned the value undefined at execution and is also of type undefined.

  • Our second point is:-
    console.log(variable); // Output: ReferenceError: variable is not defined
    

In JavaScript, a ReferenceError is thrown when trying to access a previously undeclared variable.

The behaviour of JavaScript when handling variables becomes nuanced because of hoisting. We’ll look at this in depth in subsequent sections.

Hoisting variables The following is the JavaScript lifecycle and indicative of the sequence in which variable declaration and initialisation occurs.

image.png

However, since JavaScript allows us to both declare and initialise our variables simultaneously, this is the most used pattern:

var a = 100;

It is however important to remember that in the background, JavaScript is religiously declaring then initialising our variables.

As we mentioned before, all variable and function declarations are hoisted to the top of their scope. I should also add that variable declarations are processed before any code is executed.

However, in contrast, undeclared variables do not exist until code assigning them is executed. Therefore, assigning a value to an undeclared variable implicitly creates it as a global variable when the assignment is executed. This means that, all undeclared variables are global variables.

To demonstrate this behaviour, have a look at the following:

function hoist() {
  a = 20;
  var b = 100;
}

hoist();

console.log(a); 
/* 
Accessible as a global variable outside hoist() function
Output: 20
*/

console.log(b); 
/*
Since it was declared, it is confined to the hoist() function scope.
We can't print it out outside the confines of the hoist() function.
Output: ReferenceError: b is not defined
*/

Since this is one of the eccentricities of how JavaScript handles variables, it is recommended to always declare variables regardless of whether they are in a function or global scope. This clearly delineates how the interpreter should handle them at run time.

Hope this article is helped you.