Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
16 views

Javascript

The document discusses the different data types in JavaScript including primitive types like string, number, boolean, undefined and null as well as non-primitive types like objects and functions. It also explains concepts like hoisting, implicit type coercion and equality comparisons in JavaScript.

Uploaded by

ankitbansal006
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

Javascript

The document discusses the different data types in JavaScript including primitive types like string, number, boolean, undefined and null as well as non-primitive types like objects and functions. It also explains concepts like hoisting, implicit type coercion and equality comparisons in JavaScript.

Uploaded by

ankitbansal006
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 144

Ques: What are the different data types present in javascript?

Ans: To know the type of a JavaScript variable, we can use the typeof operator.

Primitive types
String - It represents a series of characters and is written with quotes. A string
can be represented using a single or a double quote.
Example :
var str = "Vivek Singh Bisht"; //using double quotes
var str2 = 'John Doe'; //using single quotes

Number - It represents a number and can be written with or without decimals.


Example :
var x = 3; //without decimal
var y = 3.6; //with decimal

BigInt - This data type is used to store numbers which are above the limitation of
the Number data type. It can store large integers
and is represented by adding “n” to an integer literal.A BigInt value, also
sometimes just called a BigInt, is a bigint primitive, created by appending n to
the end of an integer literal, or by calling the BigInt() constructor (but without
the new operator) and giving it an integer value or string value.
Example :
var bigInteger = 234567890123456789012345678901234567890n;
const previouslyMaxSafeInteger = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
typeof 1n === 'bigint' // true
typeof BigInt('1') === 'bigint' // true
A BigInt value can also be wrapped in an Object:
typeof Object(1n) === 'object' // true

Boolean - It represents a logical entity and can have only two values : true or
false. Booleans are generally used for conditional testing.
Example :
var a = 2;
var b = 3;
var c = 2;
(a == b) // returns false
(a == c) //returns true

Undefined - When a variable is declared but not assigned, it has the value of
undefined and it’s type is also undefined.
Example :
var x; // value of x is undefined
typeof x; //undefined;
var y = undefined; // we can also set the value of a variable as undefined
typeof y; //undefined;

Null - It represents a non-existent or a invalid value.


Example :
var z = null;
typeof z; //object

Symbol - It is a new data type introduced in the ES6 version of javascript. It is


used to create an anonymous and unique value. It can be used as object keys in
JavaScript because if we are creating any object all the keys of Object should be
unique.
Example :
const s1 = Symbol();
const s2 = Symbol("some_desciption");
const s3 = Symbol("some_description");
console.log("type of s1 is - ", typeof s1);
// output - type of s1 is - symbol
console.log(s2==s3)
// output – false
In the above code we can clearly see on line number 7 type of s1 is symbol. At line
number 10 we can clearly see s2 is not equal to s3 because description of s2 and s1
are same but every time when Symbol method is called it will create unique value
and value of symbol is not dependent up on its description.

typeof of primitive types :


typeof "John Doe" // Returns "string"
typeof 3.14 // Returns "number"
typeof true // Returns "boolean"
typeof 234567890123456789012345678901234567890n // Returns bigint
typeof undefined // Returns "undefined"
typeof null // Returns "object" (kind of a bug in JavaScript)
typeof Symbol('symbol') // Returns Symbol
//not data type added extra for myself note
function aaaa() {
}
typeof aaaa; //returns 'function'

Non-primitive types
Primitive data types can store only a single value. To store multiple and complex
values, non-primitive data types are used.
Object - Used to store collection of data.
Example:
// Collection of data in key-value pairs
var obj1 = {
x: 43,
y: "Hello world!",
z: function(){
return this.x;
}
}
// Collection of data as an ordered list
var array1 = [5, "Hello", true, 4.1];
*Note- It is important to remember that any data type that is not primitive data
type, is of Object type in javascript.

Ques:2. Explain Hoisting in javascript.


Ans: Hoisting is a default behaviour of javascript where all the variable and
function declarations are moved on top.
This means that irrespective of where the variables and functions are declared,
they are moved on top of the scope. The scope can be
both local and global.

Example 1:
hoistedVariable = 3;
console.log(hoistedVariable); // outputs 3 even when the variable is declared after
it is initialized
var hoistedVariable;

Example 2:
hoistedFunction(); // Outputs " Hello world! " even when the function is declared
after calling
function hoistedFunction(){
console.log(" Hello world! ");
}

Example 3:
// Hoisting takes place in the local scope as well
function doSomething(){
x = 33;
console.log(x);
var x;
}
doSomething(); // Outputs 33 since the local variable “x” is hoisted inside the
local scope

**Note - Variable initializations are not hoisted, only variable declarations are
hoisted:
var x;
console.log(x); // Outputs "undefined" since the initialization of "x" is not
hoisted
x = 23;

**Note - To avoid hoisting, you can run javascript in strict mode by using “use
strict” on top of the code:
"use strict";
x = 23; // Gives an error since 'x' is not declared
var x;

Ques: Difference between “ == “ and “ === “ operators.


Ans: Both are comparison operators. The difference between both the operators is
that,“==” is used to compare values
whereas, “ === “ is used to compare both value and types.
Example:
var x = 2;
var y = "2";
(x == y) // Returns true since the value of both x and y is the same
(x === y) // Returns false since the typeof x is "number" and typeof y is "string"

Ques: Explain Implicit Type Coercion in javascript.


Ans: Implicit type coercion in javascript is automatic conversion of value from one
data type to another. It takes place when
the operands of an expression are of different data types.

String coercion
String coercion takes place while using the ‘ + ‘ operator. When a number is added
to a string, the number type is always
converted to the string type.
Example 1:
var x = 3;
var y = "3";
x + y // Returns "33"

Example 2:
var x = 24;
var y = "Hello";
x + y // Returns "24Hello";
**Note - ‘ + ‘ operator when used to add two numbers, outputs a number. The same ‘
+ ‘ operator when used to add two strings,
outputs the concatenated string:
var name = "Vivek";
var surname = " Bisht";

name + surname // Returns "Vivek Bisht"

Let’s understand both the examples where we have added a number to a string,

When JavaScript sees that the operands of the expression x + y are of different
types ( one being a number type and the other
being a string type ) , it converts the number type to the string type and then
performs the operation. Since after conversion,
both the variables are of string type, the ‘ + ‘ operator outputs the concatenated
string “33” in the first example and “24Hello”
in the second example.

**Note - Type coercion also takes place when using the ‘ - ‘ operator, but the
difference while using ‘ - ‘ operator is that,
a string is converted to a number and then subtraction takes place.
var x = 3;
Var y = "3";
x - y //Returns 0 since the variable y (string type) is converted to a number
type

Boolean Coercion
Boolean coercion takes place when using logical operators, ternary operators, if
statements and loop checks. To understand
boolean coercion in if statements and operators, we need to understand truthy and
falsy values.
Truthy values are those which will be converted (coerced) to true . Falsy values
are those which will be converted to false.
All values except 0, 0n, -0, “”, null, undefined and NaN are truthy values.
If statements:
Example:
var x = 0;
var y = 23;
if(x) { console.log(x) } // The code inside this block will not run since the
value of x is 0(Falsy)
if(y) { console.log(y) } // The code inside this block will run since the value
of y is 23 (Truthy)

Logical operators:
Logical operators in javascript, unlike operators in other programming languages,
do not return true or false.
They always return one of the operands.
OR ( | | ) operator - If the first value is truthy, then the first value is
returned. Otherwise, always the second value gets returned.
AND ( && ) operator - If both the values are truthy, always the second value is
returned. If the first value is falsy
then the first value is returned or if the second value is falsy then the second
value is returned.
Example:
var x = 220;
var y = "Hello";
var z = undefined;
x | | y // Returns 220 since the first value is truthy
x | | z // Returns 220 since the first value is truthy
x && y // Returns "Hello" since both the values are truthy
y && z // Returns undefined since the second value is falsy
if( x && y ){
console.log("Code runs" ); // This block runs because x && y returns "Hello"
(Truthy)
}
if( x || z ){
console.log("Code runs"); // This block runs because x || y returns 220(Truthy)
}

Equality Coercion
Equality coercion takes place when using ‘ == ‘ operator. As we have stated before
The ‘ == ‘ operator compares values and not types.
While the above statement is a simple way to explain == operator, it’s not
completely true
The reality is that while using the ‘==’ operator, coercion takes place.
The ‘==’ operator, converts both the operands to the same type and then compares
them.

Example:
var a = 12;
var b = "12";
a == b // Returns true because both 'a' and 'b' are converted to the same type and
then compared. Hence the operands are equal.
Coercion does not take place when using the ‘===’ operator. Both operands are not
converted to the same type in the case of ‘===’ operator.
Example:
var a = 226;
var b = "226";
a === b // Returns false because coercion does not take place and the operands are
of different types. Hence they are not equal.

Ques: Is javascript a statically typed or a dynamically typed language?


JavaScript is a dynamically typed language. In a dynamically typed language, the
type of a variable is checked during run-time
in contrast to statically typed language, where the type of a variable is checked
during compile-time.
Since javascript is a loosely(dynamically) typed language, variables in JS are not
associated with any type. A variable can hold
the value of any data type.
For example, a variable which is assigned a number type can be converted to a
string type:
var a = 23;
var a = "Hello World!";

Ques: What is NaN property in JavaScript?


Ans: NaN property represents “Not-a-Number” value. It indicates a value which is
not a legal number.
typeof of a NaN will return a Number .
To check if a value is NaN, we use the isNaN() function,
**Note- isNaN() function converts the given value to a Number type, and then
equates to NaN.
isNaN("Hello") // Returns true
isNaN(345) // Returns false
isNaN('1') // Returns false, since '1' is converted to Number type which results
in 0 ( a number)
isNaN(true) // Returns false, since true converted to Number type results in 1 ( a
number)
isNaN(false) // Returns false
isNaN(undefined) // Returns true

Ques: Explain passed by value and passed by reference.


Ans: In JavaScript, primitive data types are passed by value and non-primitive data
types are passed by reference.
For understanding passed by value and passed by reference, we need to understand
what happens when we create a variable and assign
a value to it,
var x = 2;
In the above example, we created a variable x and assigned it a value “2”. In the
background, the “=” (assign operator) allocates
some space in the memory, stores the value “2” and returns the location of the
allocated memory space. Therefore, the variable x
in the above code points to the location of the memory space instead of pointing to
the value 2 directly.

Assign operator behaves differently when dealing with primitive and non primitive
data types,

Assign operator dealing with primitive types:

var y = 234;
var z = y;

In the above example, assign operator knows that the value assigned to y is a
primitive type (number type in this case), so when the
second line code executes, where the value of y is assigned to z, the assign
operator takes the value of y (234) and allocates a new
space in the memory and returns the address. Therefore, variable z is not pointing
to the location of variable y, instead it is
pointing to a new location in the memory.

var y = #8454; // y pointing to address of the value 234


var z = y;
var z = #5411; // z pointing to a completely new address of the value 234

// Changing the value of y


y = 23;
console.log(z); // Returns 234, since z points to a new address in the memory so
changes in y will not effect z

From the above example, we can see that primitive data types when passed to another
variable, are passed by value. Instead of just
assigning the same address to another variable, the value is passed and new space
of memory is created.

Assign operator dealing with non-primitive types:


var obj = { name: "Vivek", surname: "Bisht" };
var obj2 = obj;

In the above example, the assign operator, directly passes the location of the
variable obj to the variable obj2. In other words,
the reference of the variable obj is passed to the variable obj2.

var obj = #8711; // obj pointing to address of { name: "Vivek", surname: "Bisht" }
var obj2 = obj;
var obj2 = #8711; // obj2 pointing to the same address
// changing the value of obj1
obj1.name = "Akki";
console.log(obj2);
// Returns {name:"Akki", surname:"Bisht"} since both the variables are pointing to
the same address.

From the above example, we can see that while passing non-primitive data types, the
assign operator directly passes the address (reference).
Therefore, non-primitive data types are always passed by reference.

Ques: What is an Immediately Invoked Function in JavaScript?


Ans: An Immediately Invoked Function ( known as IIFE and pronounced as IIFY) is a
function that runs as soon as it is defined.
Syntax of IIFE :
(function(){
// Do something;
})();

To understand IIFE, we need to understand the two sets of parentheses which are
added while creating an IIFE :
First set of parenthesis:
(function (){
//Do something;
})

While executing javascript code, whenever the compiler sees the word “function”, it
assumes that we are declaring a function in the code.
Therefore, if we do not use the first set of parentheses, the compiler throws an
error because it thinks we are declaring a function,
and by the syntax of declaring a function, a function should always have a name.

function() {
//Do something;
}
// Compiler gives an error since the syntax of declaring a function is wrong in the
code above.

To remove this error, we add the first set of parenthesis that tells the compiler
that the function is not a function declaration,
instead, it’s a function expression.

Second set of parenthesis:


(function (){
//Do something;
})();

From the definition of an IIFE, we know that our code should run as soon as it is
defined. A function runs only when it is invoked.
If we do not invoke the function, the function declaration is returned:
(function (){
// Do something;
})
// Returns the function declaration
Therefore to invoke the function, we use the second set of parenthesis.
Ques: Explain Higher Order Functions in javascript.
Functions that operate on other functions, either by taking them as arguments or by
returning them, are called higher-order functions.

Higher order functions are a result of functions being first-class citizens in


javascript.

Examples of higher order functions:


function higherOrder(fn) {
fn();
}

higherOrder(function() { console.log("Hello world") });

function higherOrder2() {
return function() {
return "Do something";
}
}

var x = higherOrder2();
x() // Returns "Do something"

Ques: Use of this keyword in regular and arrow function.


Ans: Inside of a regular JavaScript function, this value is dynamic. The dynamic
context means that the value of this depends on how the function is invoked.
let name ={ // does not create a new scope
fullName:'abc',
printInRegular: function(){
console.log(`My Name is ${this.fullName}`);
},
printInArrow:()=>console.log(`My Name is ${this.fullName}`)
}
name.printInRegular(); // My Name is abc
name.printInArrow(); // My Name is undefined
The behavior of this inside of an arrow, function differs considerably from the
regular function’s this behavior as an arrow function does not have its own “this”
keyword.
The value of this inside an arrow function remains the same throughout the
lifecycle of the function and is always bound to the value of this in the closest
non-arrow parent function which means No matter how or where being executed, this
value inside of an arrow function always equals this value from the outer function.
const myObject = {
myMethod(items) {
console.log(this); // logs myObject
const callback = () => {
console.log(this); // this takes value from myMethod(outer func)
};
items.forEach(callback);
}
};

myObject.myMethod([1, 2, 3]);

Ex: 2
'use strict';

var obj = { // does not create a new scope


i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log(this.i, this);
}
}

obj.b(); // prints undefined, Window {...} (or the global object)


obj.c(); // prints 10, Object {...}

Differences & Limitations of Arrow function:


Does not have its own bindings to this or super, and should not be used as methods.
Does not have new.target keyword.
Not suitable for call, apply and bind methods, which generally rely on establishing
a scope.
Can not be used as constructors.
Can not use yield, within its body.

Ques: Explain “this” keyword.


The “this” keyword refers to the object that the function is a property of.
The value of “this” keyword will always depend on the object that is invoking the
function.
Confused? Let’s understand the above statements by examples:
function doSomething() {
console.log(this);
}

doSomething();
What do you think the output of the above code will be?

**Note - Observe the line where we are invoking the function.

Check the definition again:


The “this” keyword refers to the object that the function is a property of.
In the above code, function is a property of which object?
Since the function is invoked in the global context, the function is a property of
the global object.

Therefore, the output of the above code will be the global object. Since we ran the
above code inside the browser,
the global object is the window object.
Example 2:
var obj = {
name: "vivek",
getName: function(){
console.log(this.name);
}
}

obj.getName();

In the above code, at the time of invocation, the getName function is a property of
the object obj , therefore, the
this keyword will refer to the object obj , and hence the output will be “vivek”.
Example 3:
var obj = {
name: "vivek",
getName: function(){
console.log(this.name);
}

var getName = obj.getName;


var obj2 = {name:"akshay", getName };
obj2.getName();

Can you guess the output here?


The output will be “akshay”.

Although the getName function is declared inside the object obj , at the time of
invocation, getName() is a property of obj2 ,
therefore the “this” keyword will refer to obj2 .
The silly way to understanding the this keyword is, whenever the function is
invoked, check the object before the dot .
The value of this . keyword will always be the object before the dot .
If there is no object before the dot like in example1, the value of this keyword
will be the global object.

Example 4:
var obj1 = {
address : "Mumbai,India",
getAddress: function(){
console.log(this.address);
}
}

var getAddress = obj1.getAddress;


var obj2 = {name:"akshay"};
obj2.getAddress();

Can you guess the output?


The output will be an error.
Although in the code above, the this keyword refers to the object obj2 , obj2 does
not have the property “address”‘,
hence the getAddress function throws an error.

Ques: Explain call(), apply() and, bind() methods.


Ans:
call()
It’s a predefined method in javascript.
This method invokes a method (function) by specifying the owner object.
Example 1:
function sayHello(){
return "Hello " + this.name;
}
var obj = {name: "Sandy"};
sayHello.call(obj);
// Returns "Hello Sandy"

call() method allows an object to use the method (function) of another object.
Example 2:
var person = {
age: 23,
getAge: function(){
return this.age;
}
}

var person2 = {age: 54};


person.getAge.call(person2);
// Returns 54

call() accepts arguments:

function saySomething(message){
return this.name + " is " + message;
}

var person4 = {name: "John"};

saySomething.call(person4, "awesome");
// Returns "John is awesome"

apply()

The apply method is similar to the call() method. The only difference is that,
call() method takes arguments separately whereas, apply() method takes arguments as
an array.

function saySomething(message){
return this.name + " is " + message;
}
var person4 = {name: "John"};
saySomething.apply(person4, ["awesome"]);

bind()
This method returns a new function, where the value of “this” skeyword will be
bound to the owner object, which is provided as a parameter.
Example with arguments:
var bikeDetails = {
displayDetails: function(registrationNumber,brandName){
return this.name+ " , "+ "bike details: "+ registrationNumber + " , " +
brandName;
}
}

var person1 = {name: "Vivek"};

var detailsOfPerson1 = bikeDetails.displayDetails.bind(person1, "TS0122",


"Bullet");

// Binds the displayDetails function to the person1 object

detailsOfPerson1();
// Returns Vivek, bike details: TS0452, Thunderbird

Ques: What is currying in JavaScript?


Ans: Currying is an advanced technique to transform a function of arguments n, to n
functions of one or less arguments.
Example of a curried function:
function add (a) {
return function(b){
return a + b;
}
}
add(3)(4)

For Example, if we have a function f(a,b) , then the function after currying, will
be transformed to f(a)(b).

By using the currying technique, we do not change the functionality of a function,


we just change the way it is invoked.
Let’s see currying in action:

function multiply(a,b){
return a*b;
}

function currying(fn){
return function(a){
return function(b){
return fn(a,b);
}
}
}

var curriedMultiply = currying(multiply);

multiply(4, 3); // Returns 12


curriedMultiply(4)(3); // Also returns 12
As one can see in the code above, we have transformed the function multiply(a,b) to
a function curriedMultiply ,
which takes in one parameter at a time.

Ques: Explain Scope and Scope Chain in javascript.


Scope in JS, determines the accessibility of variables and functions at various
parts in one’s code.
In general terms, the scope will let us know at a given part of code, what are the
variables and functions that we can or cannot access.

There are three types of scopes in JS:

Global Scope
Local or Function Scope
Block Scope

Global Scope
Variables or functions declared in the global namespace have global scope, which
means all the variables and functions having global
scope can be accessed from anywhere inside the code

var globalVariable = "Hello world";


function sendMessage(){
return globalVariable; // can access globalVariable since it's written in global
space
}
function sendMessage2(){
return sendMessage(); // Can access sendMessage function since it's written in
global space
}

sendMessage2(); // Returns “Hello world”

Function Scope

Any variables or functions declared inside a function have local/function scope,


which means that all the variables and functions
declared inside a function, can be accessed from within the function and not
outside of it.

function awesomeFunction(){
var a = 2;

var multiplyBy2 = function(){


console.log(a*2); // Can access variable "a" since a and multiplyBy2 both are
written inside the same function
}
}
console.log(a); // Throws reference error since a is written in local scope and
cannot be accessed outside

multiplyBy2(); // Throws reference error since multiplyBy2 is written in local


scope

Block Scope

Block scope is related to the variables declared using let and const. Variables
declared with var do not have block scope.
Block scope tells us that any variable declared inside a block { }, can be accessed
only inside that block and cannot be accessed outside of it.

{
let x = 45;
}

console.log(x); // Gives reference error since x cannot be accessed outside of the


block

for(let i=0; i<2; i++){


// do something
}

console.log(i); // Gives reference error since i cannot be accessed outside of the


for loop block

Scope Chain
JavaScript engine also uses Scope to find variables.
Let’s understand that using an example:
var y = 24;
function favFunction(){
var x = 667;
var anotherFavFunction = function(){
console.log(x); // Does not find x inside anotherFavFunction, so looks for
variable inside favFunction, outputs 667
}
var yetAnotherFavFunction = function(){
console.log(y); // Does not find y inside yetAnotherFavFunction, so looks for
variable inside favFunction and does not find it,
so looks for variable in global scope, finds it and outputs 24
}

anotherFavFunction();
yetAnotherFavFunction();
}

favFunction();
As you can see in the code above, if the javascript engine does not find the
variable in local scope, it tries to check
for the variable in the outer scope.
If the variable does not exist in the outer scope, it tries to find the variable in
the global scope.

If the variable is not found in the global space as well, reference error is
thrown.

Ques:Explain Closures in JavaScript.


Ans: Scalar youtube video:
https://www.youtube.com/watch?v=QySYYEUHLbU&t=857s

var func= function() {


var a =2;
var set_a = function(newVal) {
a = newVal;
}
var get_a = function() {
return a;
}
return {
getA : get_a,
setA : set_a
};
}

obj = function();
obj.getA(); //print 2
obj.setA(10); //set value 10
obj.getA(); //print 10

Closure is having the capability to have some data which will be closed inside the
function, it will be closed in a way
that only references that you are creating will be able to operate on the data
inside the function.
This can be related with private variable concept of java or c++.

Other explanation:

Closures is an ability of a function to remember the variables and functions that


are declared in its outer scope.

var Person = function(pName){


var name = pName;
this.getName = function(){
return name;
}
}

var person = new Person("Neelesh");


console.log(person.getName());

Let’s understand closures by example:

function randomFunc(){
var obj1 = {name:"Vivian", age:45};

return function(){
console.log(obj1.name + " is "+ "awesome"); // Has access to obj1 even when the
randomFunc function is executed

}
}

var initialiseClosure = randomFunc(); // Returns a function

initialiseClosure();

Let’s understand the code above,

The function randomFunc() gets executed and returns a function when we assign it to
a variable:

var initialiseClosure = randomFunc();

The returned function is then executed when we invoke initialiseClosure:

initialiseClosure();

The line of code above outputs “Vivian is awesome” and this is possible because of
closure.

When the function randomFunc() runs, it sees that the returning function is using
the variable obj1 inside it:

console.log(obj1.name + " is "+ "awesome");

Therefore randomFunc(), instead of destroying the value of obj1 after execution,


saves the value in the memory for further reference.
This is the reason why the returning function is able to use the variable declared
in the outer scope even after the function is already executed.

This ability of a function to store a variable for further reference even after it
is executed, is called Closure.

Ques:What are object prototypes?


All javascript objects inherit properties from a prototype.

For example,
Date objects inherit properties from the Date prototype
Math objects inherit properties from the Math prototype
Array objects inherit properties from the Array prototype.
On top of the chain is Object.prototype. Every prototype inherits properties and
methods from the Object.prototype.
A prototype is a blueprint of an object. Prototype allows us to use properties and
methods on an object even if the properties and methods
do not exist on the current object.

Let’s see prototypes help us use methods and properties:

var arr = [];


arr.push(2);

console.log(arr); // Outputs [2]

In the code above, as one can see, we have not defined any property or method
called push on the array “arr”
but the javascript engine does not throw an error.

The reason being the use of prototypes. As we discussed before, Array objects
inherit properties from the Array prototype.

The javascript engine sees that the method push does not exist on the current array
object and therefore,
looks for the method push inside the Array prototype and it finds the method.

Whenever the property or method is not found on the current object, the javascript
engine will always try to look in its prototype
and if it still does not exist, it looks inside the prototype's prototype and so
on.

Ques: Prototypical Inheritance


Ans:
Prototype: its a property of an object, it is either an object or null value and in
each prototype we have __proto__ property.
Its nothing but just a pointer to the prootype of the object.
An object can have lots of properties but it can have only one prototype property
which can either be null or object.
var a = {
x: 10,
calculate: function(z) {
return this.x + this.y + z;
}
}
var b = {
y: 20,
__proto__: a
}
__proto__ is a internal property of object which is used to point to the
prototype.This is used to do the inheritance internally.

var c = {
y: 30,
__proto__: a
}

//call the inherited method


console.log(b.calculate(30)); //60
console.log(b.calculate(40)); //80

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

the above thing is done internally like this:


var p = Object.create(a, {y: {value:20}});
var q= Object.create(a, {y: {value:30}});

console.log(p);
console.log(q);

Different way of inheritance: using constructor function

//a constructor function


function Foo(y) {
//which may create objects
//by specified pattern: they have after
//creation own y property
this.y =y;
}

also Foo.prototype stores reference to the property of newly created objects, so we


may use it to define shared/inherited properties or methods,
so the same as in previous example we have

//inherited property of x
Foo.prototype.x = 10;

//and inherited method calculate


Foo.prototype.calculate = function (z) {
return this.x + this.y + z;
}

//now we create our b and c objects using pattern Foo


var b = new Foo(20);
var c = new Foo(30);

//call the inherited method


console.log(b.calculate(30)); //60
console.log(b.calculate(40)); //80

// let's show that we reference


// properties we expect
console.log(

b.__proto__ === Foo.prototype, // true


c.__proto__ === Foo.prototype, // true

// also "Foo.prototype" automatically creates


// a special property "constructor", which is a
// reference to the constructor function itself;
// instances "b" and "c" may found it via
// delegation and use to check their constructor

b.constructor === Foo, // true


c.constructor === Foo, // true
Foo.prototype.constructor === Foo, // true
b.calculate === b.__proto__.calculate, // true
b.__proto__.calculate === Foo.prototype.calculate // true

);

A constructor function is used to create an object, it can be called as class in


JS. A constructor function with the internal properties
and prototype properties can be called as a class.

Every constructor function by default get the proptype object property.


A proptype object is a object where can put what you want to be inherited.

A proptype chain is a finite chain of objects which is used to implement


inheritance and shared properties.

If a prototype is not specified for an object explicitly, then the default value
for __proto__ is taken — Object.prototype.
Object Object.prototype itself also has a __proto__, which is the final link of a
chain and is set to null.

This figure again shows that every object has a prototype. Constructor function Foo
also has its own __proto__ which is Function.prototype,
and which in turn also references via its __proto__ property again to the
Object.prototype. Thus, repeat, Foo.prototype is just an explicit
property of Foo which refers to the prototype of b and c objects.

Formally, if to consider a concept of a classification (and we’ve exactly just now


classified the new separated thing — Foo), a
combination of the constructor function and the prototype object may be called as a
“class”. Actually, e.g. Python’s first-class
dynamic classes have absolutely the same implementation of properties/methods
resolution. From this viewpoint, classes of Python
are just a syntactic sugar for delegation based inheritance used in ECMAScript.

Ques: What are callbacks?


A callback is a function that will be executed after another function gets
executed.

In javascript, functions are treated as first-class citizens, they can be used as


an argument of another function, can be returned
by another function and can be used as a property of an object.

Functions that are used as an argument to another function are called callback
functions.

Example:
function divideByHalf(sum){
console.log(Math.floor(sum / 2));
}

function multiplyBy2(sum){
console.log(sum * 2);
}

function operationOnSum(num1,num2,operation){
var sum = num1 + num2;
operation(sum);
}

operationOnSum(3, 3, divideByHalf); // Outputs 3


operationOnSum(5, 5, multiplyBy2); // Outputs 20
In the code above, we are performing mathematical operations on the sum of two
numbers.
The operationOnSum function takes 3 arguments, first number, second number, and the
operation that is to be performed on their sum (callback) .
Both divideByHalf and multiplyBy2 functions are used as callback functions in the
code above.
These callback functions will be executed only after the function operationOnSum is
executed.
Therefore, callback is a function that will be executed after another function gets
executed.

Ques:What is memoization?
Memoization is a form of caching where the return value of a function is cached
based on its parameters. If the parameter of that
function is not changed, the cached version of the function is returned.

Let’s understand memoization, by converting a simple function to a memoized


function:

**Note- Memoization is used for expensive function calls but in the following
example, we are considering a simple function for
understanding the concept of memoization better.

Consider the following function:

function addTo256(num){
return num + 256;
}

addTo256(20); // Returns 276


addTo256(40); // Returns 296
addTo256(20); // Returns 276

In the code above, we have written a function that adds the parameter to 256 and
returns it.

When we are calling the function addTo256 again with the same parameter (“20” in
the case above), we are computing the result
again for the same parameter.

Computing the result with the same parameter again and again is not a big deal in
the above case, but imagine if the function does
some heavy duty work, then, computing the result again and again with the same
parameter will lead to wastage of time.

This is where memoization comes in, by using memoization we can store(cache) the
computed results based on the parameters. If the
same parameter is used again while invoking the function, instead of computing the
result, we directly return the stored (cached) value.

Let’s convert the above function addTo256, to a memoized function:

function memoizedAddTo256(){
var cache = {};

return function(num){
if(num in cache){
console.log("cached value");
return cache[num]

}
else{
cache[num] = num + 256;
return cache[num];
}
}
}

var memoizedFunc = memoizedAddTo256();

memoizedFunc(20); // Normal return


memoizedFunc(20); // Cached return

In the code above, if we run memoizedFunc function with the same parameter, instead
of computing the result again,
it returns the cached result.

**Note- Although using memoization saves time, it results in larger consumption of


memory since we are storing all the computed results.

Ques: What is recursion in a programming language?


Recursion is a technique to iterate over an operation by having a function call
itself repeatedly until it arrives at a result.
function add(number) {
if (number <= 0) {
return 0;
} else {
return number + add(number - 1);
}
}

add(3) => 3 + add(2)


3 + 2 + add(1)
3 + 2 + 1 + add(0)
3 + 2 + 1 + 0 = 6
Example of a recursive function:

The following function calculates the sum of all the elements in an array by using
recursion:
function computeSum(arr){
if(arr.length === 1){
return arr[0];
}
else{
return arr.pop() + computeSum(arr);
}
}
computeSum([7, 8, 9, 99]); // Returns 123

Ques:What is the use of a constructor function in javascript?


Constructor functions are used to create objects in javascript.

When do we use constructor functions?


If we want to create multiple objects having similar properties and methods,
constructor functions are used.

**Note- Name of a constructor function should always be written in Pascal Notation:


every word should start with a capital letter.

Example:
function Person(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
}

var person1 = new Person("Vivek", 76, "male");


console.log(person1);

var person2 = new Person("Courtney", 34, "female");


console.log(person2);

In the code above, we have created a constructor function named Person.


Whenever we want to create a new object of the type Person,
We need to create it using the new keyword:
var person3 = new Person("Lilly", 17, "female");
The above line of code will create a new object of the type Person.
Constructor functions allow us to group similar objects.

Ques: What is DOM?


DOM stands for Document Object Model.

DOM is a programming interface for HTML and XML documents.

When the browser tries to render a HTML document, it creates an object based on the
HTML document called DOM. Using this DOM,
we can manipulate or change various elements inside the HTML document.

Ques:What are arrow functions?


Arrow functions were introduced in the ES6 version of javascript.
They provide us with a new and shorter syntax for declaring functions.
Arrow functions can only be used as a function expression.
Let’s compare the normal function declaration and the arrow function declaration in
detail:

// Traditional Function Expression


var add = function(a,b){
return a + b;
}

// Arrow Function Expression


var arrowAdd = (a,b) => a + b;

Arrow functions are declared without the function keyword. If there is only one
returning expression then we don’t need to use the
return keyword as well in an arrow function as shown in the example above. Also,
for functions having just one line of code,
curly braces { } can be omitted.

// Traditional function expression


var multiplyBy2 = function(num){
return num * 2;
}
// Arrow function expression
var arrowMultiplyBy2 = num => num * 2;

If the function takes in only one argument, then the parenthesis () around the
parameter can be omitted as shown in the code above.

var obj1 = {
valueOfThis: function(){
return this;
}
}
var obj2 = {
valueOfThis: ()=>{
return this;
}
}

obj1.valueOfThis(); // Will return the object obj1


obj2.valueOfThis(); // Will return window/global object

The biggest difference between the traditional function expression and the arrow
function, is the handling of the this keyword.
By general definition, the this keyword always refers to the object that is calling
the function.
As you can see in the code above, obj1.valueOfThis() returns obj1, since this
keyword refers to the object calling the function.
In the arrow functions, there is no binding of the this keyword.
The this keyword inside an arrow function, does not refer to the object calling it.
It rather inherits its value from the
parent scope which is the window object in this case.

Therefore, in the code above, obj2.valueOfThis() returns the window object.

Ques:Differences between declaring variables using var, let and const.


Before the ES6 version of javascript, only the keyword var was used to declare
variables.

With the ES6 Version, keywords let and const were introduced to declare variables.

keyword const let var


global scope no no yes
function scope yes yes yes
block scope yes yes no
can be reassigned no yes yes

Let’s understand the differences with examples:


var variable1 = 23;
let variable2 = 89;

function catchValues(){
console.log(variable1);
console.log(variable2);
// Both the variables can be accessed anywhere since they are declared in the
global scope
}

window.variable1; // Returns the value 23


window.variable2; // Returns undefined

The variables declared with the let keyword in the global scope behave just
like the variable declared with the var keyword in the global scope.

Variables declared in the global scope with var and let keywords can be accessed
from anywhere in the code.

But, there is one difference !

Variables that are declared with the var keyword in the global scope are added to
the window/global object.
Therefore, they can be accessed using window.variableName.

Whereas, the variables declared with the let keyword are not added to the global
object, therefore, trying to access
such variables using window.variableName results in an error.

var vs let in functional scope

function varVsLetFunction(){
let awesomeCar1 = "Audi";
var awesomeCar2 = "Mercedes";
}

console.log(awesomeCar1); // Throws an error


console.log(awesomeCar2); // Throws an error

Variables declared in a functional/local scope using var and let keywords behave
exactly the same, meaning ,
they cannot be accessed from outside of the scope.

{
var variable3 = [1, 2, 3, 4];
}

console.log(variable3); // Outputs [1,2,3,4]

{
let variable4 = [6, 55, -1, 2];
}

console.log(variable4); // Throws error

for(let i = 0; i < 2; i++){


//Do something
}

console.log(i); // Throws error

for(var j = 0; j < 2; i++){


// Do something
}
console.log(j) // Outputs 2

In javascript, a block means the code written inside the curly braces {} .

Variables declared with var keyword do not have block scope. It means a variable
declared in block scope {} with the
var keyword is the same as declaring the variable in the global scope.

Variables declared with let keyword inside the block scope cannot be accessed from
outside of the block.

Const keyword

Variables with the const keyword behave exactly like a variable declared with the
let keyword with only one difference,
any variable declared with the const keyword cannot be reassigned.

Example:

const x = {name:"Vivek"};

x = {address: "India"}; // Throws an error

x.name = "Nikhil"; // No error is thrown

const y = 23;

y = 44; // Throws an error

In the code above, although we can change the value of a property inside the
variable declared with const keyword,
we cannot completely reassign the variable itself.

Ques: What is the rest parameter and spread operator?


Both rest parameter and spread operator were introduced in the ES6 version of
javascript.

Rest parameter ( … )

It provides an improved way of handling parameters of a function.

Using the rest parameter syntax, we can create functions that can take a variable
number of arguments.

Any number of arguments will be converted into an array using the rest parameter.

It also helps in extracting all or some parts of the arguments.

Rest parameter can be used by applying three dots (...) before the parameters.

function extractingArgs(...args){
return args[1];
}

// extractingArgs(8,9,1); // Returns 9

function addAllArgs(...args){
let sumOfArgs = 0;
let i = 0;
while(i < args.length){
sumOfArgs += args[i];
i++;
}
return sumOfArgs;
}

addAllArgs(6, 5, 7, 99); // Returns 117


addAllArgs(1, 3, 4); // Returns 8

**Note- Rest parameter should always be used at the last parameter of a function:

// Incorrect way to use rest parameter


function randomFunc(a,...args,c){
//Do something
}

// Correct way to use rest parameter


function randomFunc2(a,b,...args){
//Do something
}

Spread operator (…)

Although the syntax of spread operator is exactly the same as the rest parameter,
spread operator is used to spread an array,
and object literals. We also use spread operators where one or more arguments are
expected in a function call.

function addFourNumbers(num1,num2,num3,num4){
return num1 + num2 + num3 + num4;
}

let fourNumbers = [5, 6, 7, 8];

addFourNumbers(...fourNumbers);
// Spreads [5,6,7,8] as 5,6,7,8

let array1 = [3, 4, 5, 6];


let clonedArray1 = [...array1];
// Spreads the array into 3,4,5,6
console.log(clonedArray1); // Outputs [3,4,5,6]

let obj1 = {x:'Hello', y:'Bye'};


let clonedObj1 = {...obj1}; // Spreads and clones obj1
console.log(obj1);

let obj2 = {z:'Yes', a:'No'};


let mergedObj = {...obj1, ...obj2}; // Spreads both the objects and merges it
console.log(mergedObj);
// Outputs {x:'Hello', y:'Bye',z:'Yes',a:'No'};

***Note- Key differences between rest parameter and spread operator:


Rest parameter is used to take a variable number of arguments and turns into an
array while the spread operator takes an
array or an object and spreads it
Rest parameter is used in function declaration whereas the spread operator is used
in function calls.

Ques: What is the use of promises in javascript?


Promises are used to handle asynchronous operations in javascript.

Before promises, callbacks were used to handle asynchronous operations. But due to
limited functionality of callback, using multiple
callbacks to handle asynchronous code can lead to unmanageable code.

Promise object has four states -

Pending - Initial state of promise. This state represents that the promise has
neither been fulfilled nor been rejected, it is in the pending state.
Fulfilled - This state represents that the promise has been fulfilled, meaning the
async operation is completed.
Rejected - This state represents that the promise has been rejected for some
reason, meaning the async operation has failed.
Settled - This state represents that the promise has been either rejected or
fulfilled.

A promise is created using the Promise constructor which takes in a callback


function with two parameters, resolve and reject respectively.

resolve is a function that will be called, when the async operation has been
successfully completed.

reject is a function that will be called, when the async operation fails or if some
error occurs.

Example of a promise:

Promises are used to handle asynchronous operations like server requests, for the
ease of understanding, we are using an operation to
calculate the sum of three elements.

In the function below, we are returning a promise inside a function:

function sumOfThreeElements(...elements){
return new Promise((resolve,reject)=>{
if(elements.length > 3 ){
reject("Only three elements or less are allowed");
}
else{
let sum = 0;
let i = 0;
while(i < elements.length){
sum += elements[i];
i++;
}
resolve("Sum has been calculated: "+sum);
}
})
}

In the code above, we are calculating the sum of three elements, if the length of
elements array is more than 3, promise is rejected,
else the promise is resolved and the sum is returned.

We can consume any promise by attaching then() and catch() methods to the consumer.
then() method is used to access the result when the promise is fulfilled.

catch() method is used to access the result/error when the promise is rejected.

In the code below, we are consuming the promise:

sumOfThreeElements(4, 5, 6)
.then(result=> console.log(result))
.catch(error=> console.log(error));
// In the code above, the promise is fulfilled so the then() method gets executed

sumOfThreeElements(7, 0, 33, 41)


.then(result => console.log(result))
.catch(error=> console.log(error));
// In the code above, the promise is rejected hence the catch() method gets
executed

Ques: What are classes in javascript?


Introduced in the ES6 version, classes are nothing but syntactic sugars for
constructor functions.

They provide a new way of declaring constructor functions in javascript.

Below are the examples of how classes are declared and used:

// Before ES6 version, using constructor functions


function Student(name,rollNumber,grade,section){
this.name = name;
this.rollNumber = rollNumber;
this.grade = grade;
this.section = section;
}

// Way to add methods to a constructor function


Student.prototype.getDetails = function(){
return 'Name: ${this.name}, Roll no: ${this.rollNumber}, Grade: ${this.grade},
Section:${this.section}';
}

let student1 = new Student("Vivek", 354, "6th", "A");


student1.getDetails();
// Returns Name: Vivek, Roll no:354, Grade: 6th, Section:A

// ES6 version classes


class Student{
constructor(name,rollNumber,grade,section){
this.name = name;
this.rollNumber = rollNumber;
this.grade = grade;
this.section = section;
}

// Methods can be directly added inside the class


getDetails(){
return 'Name: ${this.name}, Roll no: ${this.rollNumber}, Grade:${this.grade},
Section:${this.section}';
}
}

let student2 = new Student("Garry", 673, "7th", "C");


student2.getDetails();
// Returns Name: Garry, Roll no:673, Grade: 7th, Section:C

Key points to remember about classes:

Unlike functions, classes are not hoisted. A class cannot be used before it is
declared.
A class can inherit properties and methods from other classes by using the extend
keyword.
All the syntaxes inside the class must follow the strict mode(‘use strict’) of
javascript.
Error will be thrown if the strict mode rules are not followed.

Ques:What are generator functions?


Introduced in ES6 version, generator functions are a special class of functions.
They can be stopped midway and then continue from where it had stopped.
Generator functions are declared with the function* keyword instead of the normal
function keyword:

function* genFunc(){
// Perform operation
}

In normal functions, we use the return keyword to return a value and as soon as the
return statement gets executed,
the function execution stops:
function normalFunc(){
return 22;
console.log(2); // This line of code does not get executed
}

In the case of generator functions, when called, they do not execute the code,
instead they return a generator object .
This generator object handles the execution.
function* genFunc(){
yield 3;
yield 4;
}
genFunc(); // Returns Object [Generator] {}

The generator object consists of a method called next() , this method when called,
executes the code until the nearest yield statement,
and returns the yield value.

For example if we run the next() method on the above code:

genFunc().next(); // Returns {value: 3, done:false}

As one can see the next method returns an object consisting of value and done
properties.
Value property represents the yielded value.
Done property tells us whether the function code is finished or not. (Returns true
if finished)
Generator functions are used to return iterators. Let’s see an example where an
iterator is returned:

function* iteratorFunc() {
let count = 0;
for (let i = 0; i < 2; i++) {
count++;
yield i;
}
return count;
}

let iterator = iteratorFunc();


console.log(iterator.next()); // {value:0,done:false}
console.log(iterator.next()); // {value:1,done:false}
console.log(iterator.next()); // {value:2,done:true}

As you can see in the code above, the last line returns done:true , since the code
reaches the return statement.

Ques: Explain WeakSet in javascript.


In javascript, Set is a collection of unique and ordered elements.
Just like Set, WeakSet is also a collection of unique and ordered elements with
some key differences:
Weakset contains only objects and no other type.
An object inside the weakset is referenced weakly. This means, if the object inside
the weakset does not have a reference,
it will be garbage collected.
Unlike Set, WeakSet only has three methods, add() , delete() and has() .

const newSet = new Set([4, 5, 6, 7]);


console.log(newSet);// Outputs Set {4,5,6,7}

const newSet2 = new WeakSet([3, 4, 5]); //Throws an error

let obj1 = {message:"Hello world"};


const newSet3 = new WeakSet([obj1]);
console.log(newSet3.has(obj1)); // true

Ques: Explain WeakMap in javascript.


In javascript, Map is used to store key-value pairs. The key-value pairs can be of
both primitive and non-primitive types.
WeakMap is similar to Map with key differences:
The keys and values in weakmap should always be an object.
If there are no references to the object, the object will be garbage collected.

const map1 = new Map();


map1.set('Value', 1);

const map2 = new WeakMap();


map2.set('Value', 2.3); // Throws an error

let obj = {name:"Vivek"};


const map3 = new WeakMap();
map3.set(obj, {age:23});
Ques: What is Object Destructuring?
Object destructuring is a new way to extract elements from an object or an array.

Object destructuring:

Before ES6 version:

const classDetails = {
strength: 78,
benches: 39,
blackBoard:1
}

const classStrength = classDetails.strength;


const classBenches = classDetails.benches;
const classBlackBoard = classDetails.blackBoard;

The same example using object destructuring:

const classDetails = {
strength: 78,
benches: 39,
blackBoard:1
}

const {strength:classStrength, benches:classBenches,blackBoard:classBlackBoard} =


classDetails;

console.log(classStrength); // Outputs 78
console.log(classBenches); // Outputs 39
console.log(classBlackBoard); // Outputs 1

As one can see, using object destructuring we have extracted all the elements
inside an object in one line of code.

If we want our new variable to have the same name as the property of an object we
can remove the colon:

const {strength:strength} = classDetails;


// The above line of code can be written as:
const {strength} = classDetails;

Array destructuring:

Before ES6 version:

const arr = [1, 2, 3, 4];


const first = arr[0];
const second = arr[1];
const third = arr[2];
const fourth = arr[3];

The same example using object destructuring:

const arr = [1, 2, 3, 4];


const [first,second,third,fourth] = arr;
console.log(first); // Outputs 1
console.log(second); // Outputs 2
console.log(third); // Outputs 3
console.log(fourth); // Outputs 4

Ques: What is a Temporal Dead Zone?


Temporal Dead Zone is a behaviour that occurs with variables declared using let and
const keywords.
It is a behaviour where we try to access a variable before it is initialized.

Examples of temporal dead zone:

x = 23; // Gives reference error


let x;
function anotherRandomFunc(){
message = "Hello"; // Throws a reference error

let message;
}
anotherRandomFunc();

In the code above, both in global scope and functional scope, we are trying to
access variables which have not been declared yet.
This is called the Temporal Dead Zone

Ques: Guess the outputs of the following codes:


Ans:
a) // Code 1:
function func1(){
setTimeout(()=>{
console.log(x);
console.log(y);
},3000);

var x = 2;
let y = 12;
}
func1();
Code 1 - Outputs 2 and 12 . Since, even though let variables are not hoisted, due
to async nature of javascript, the complete function
code runs before the setTimeout function. Therefore, it has access to both x and y.

b) // Code 2:
function func2(){
for(var i = 0; i < 3; i++){
setTimeout(()=> console.log(i),2000);
}
}
func2();
Code 2 - Outputs 3 , three times since variable declared with var keyword does not
have block scope. Also, inside the for loop,
the variable i is incremented first and then checked.

c) // Code 3:
(function(){
setTimeout(()=> console.log(1),2000);
console.log(2);
setTimeout(()=> console.log(3),0);
console.log(4);
})();
Code 3 - Output in the following order:
2
4
3
1 // After two seconds
Even though the second timeout function has a waiting time of zero seconds, the
javascript engine always evaluates the setTimeout
function using the Web API and therefore, the complete function executes before the
setTimeout function can execute.

d) // Code 1:
let x= {}, y = {name:"Ronny"},z = {name:"John"};
x[y] = {name:"Vivek"};
x[z] = {name:"Akki"};
console.log(x[y]);
Ans:
Code 1 - Output will be {name: “Akki”}.
Adding objects as properties of another object should be done carefully.
Writing x[y] = {name:”Vivek”} , is same as writing x[‘object Object’] =
{name:”Vivek”} ,
While setting a property of an object, javascript coerces the parameter into a
string.
Therefore, since y is an object, it will be converted to ‘object Object’.

e) // Code 2:
function runFunc(){
console.log("1" + 1);
console.log("A" - 1);
console.log(2 + "-2" + "2");
console.log("Hello" - "World" + 78);
console.log("Hello"+ "78");
}
runFunc();
Ans:
Code 2 - Outputs in the following order:
11
Nan
2-22
NaN
Hello78

f) // Code 3:
let a = 0;
let b = false;
console.log((a == b));
console.log((a === b));
Code 3 - Output in the following order due to equality coercion:
true
false

g) //code 4
var x = 23;

(function(){
var x = 43;
(function random(){
x++;
console.log(x);
var x = 21;
})();
})();

Answer:
Output is NaN .
random() function has functional scope, since x is declared and hoisted in the
functional scope.
Rewriting the random function will give a better idea about the output:
function random(){
var x; // x is hoisted
x++; // x is not a number since it is not initialized yet
console.log(x); // Outputs NaN
x = 21; // Initialization of x
}

Ques: Guess the outputs of the following code:


// Code 1

let hero = {
powerLevel: 99,
getPower(){
return this.powerLevel;
}
}

let getPower = hero.getPower;

let hero2 = {powerLevel:42};


console.log(getPower());
console.log(getPower.apply(hero2));

// Code 2

const a = function(){
console.log(this);

const b = {
func1: function(){
console.log(this);
}
}

const c = {
func2: ()=>{
console.log(this);
}
}
b.func1();
c.func2();
}

a();

// Code 3

const b = {
name:"Vivek",
f: function(){
var self = this;
console.log(this.name);
(function(){
console.log(this.name);
console.log(self.name);
})();
}
}

b.f();

Code 1 - Output in the following order:

undefined
42

Reason - The first output is undefined since when the function is invoked, it is
invoked referencing the global object:

window.getPower() = getPower();

Code 2 - Outputs in the following order:

global/window object
object "b"
global/window object

Since we are using arrow function inside func2, this keyword refers to the global
object.

Code 3 - Outputs in the following order:

"Vivek"
undefined
"Vivek"

Only in the IIFE inside the function f , the this keyword refers to the
global/window object.

Ques:Guess the outputs of the following code:


**Note - Code 2 and Code 3 require you to modify the code, instead of guessing the
output.
// Code 1
(function(a){
return (function(){
console.log(a);
a = 23;
})()
})(45);

// Code 2
// Each time bigFunc is called, an array of size 700 is being created,
// Modify the code so that we don't create the same array again and again

function bigFunc(element){
let newArray = new Array(700).fill('♥');
return newArray[element];
}

console.log(bigFunc(599)); // Array is created


console.log(bigFunc(670)); // Array is created again

// Code 3
// The following code outputs 2 and 2 after waiting for one second
// Modify the code to output 0 and 1 after one second.

function randomFunc(){
for(var i = 0; i < 2; i++){
setTimeout(()=> console.log(i),1000);
}
}

randomFunc();

Answers -

Code 1 - Outputs 45 .

Even though a is defined in the outer function, due to closure the inner functions
have access to it.

Code 2 - This code can be modified by using closures,

function bigFunc(){
let newArray = new Array(700).fill('♥');
return (element) => newArray[element];
}

let getElement = bigFunc(); // Array is created only once


getElement(599);
getElement(670);

Code 3 - Can be modified in two ways:

Using let keyword:

function randomFunc(){
for(let i = 0; i < 2; i++){
setTimeout(()=> console.log(i),1000);
}
}

randomFunc();
Using closure:

function randomFunc(){
for(var i = 0; i < 2; i++){
(function(i){
setTimeout(()=>console.log(i),1000);
})(i);
}
}

randomFunc();

Ques: Write a function that performs binary search on a sorted array.


Answer:

function binarySearch(arr,value,startPos,endPos){
if(startPos > endPos) return -1;

let middleIndex = Math.floor(startPos+endPos)/2;

if(arr[middleIndex] === value) return middleIndex;

elsif(arr[middleIndex] > value){


return binarySearch(arr,value,startPos,middleIndex-1);
}
else{
return binarySearch(arr,value,middleIndex+1,endPos);
}
}

Ques: Implement a function that returns an updated array with r right rotations on
an array of integers a .
Example:
Given the following array:
[2,3,4,5,7]
Perform 3 right rotations:
First rotation : [7,2,3,4,5] , Second rotation : [5,7,2,3,4] and, Third rotation:
[4,5,7,2,3]
return [4,5,7,2,3]

Answer:
function rotateRight(arr,rotations){
if(rotations == 0) return arr;
for(let i = 0; i < rotations;i++){
let element = arr.pop();
arr.unshift(element);
}
return arr;
}
rotateRight([2, 3, 4, 5, 7], 3); // Return [4,5,7,2,3]
rotateRight([44, 1, 22, 111], 5); // Returns [111,44,1,22]
#########################Edureka##################################33

Ques: What is the difference between Local storage & Session storage?
Ans: Local Storage – The data is not sent back to the server for every HTTP request
(HTML, images, JavaScript, CSS, etc) –
reducing the amount of traffic between client and server. It will stay until it is
manually cleared through settings or program.

Session Storage – It is similar to local storage; the only difference is while data
stored in local storage has no expiration time,
data stored in session storage gets cleared when the page session ends. Session
Storage will leave when the browser is closed.

Ques: What is the difference between null & undefined?


Ans: Undefined means a variable has been declared but has not yet been assigned a
value. On the other hand, null is an assignment value.
It can be assigned to a variable as a representation of no value. Also, undefined
and null are two distinct types: undefined is a
type itself (undefined) while null is an object.

Ques:What is an event bubbling in JavaScript?


Ans: Event bubbling is a way of event propagation in the HTML DOM API, when an
event occurs in an element inside another element,
and both elements have registered a handle for that event. With bubbling, the event
is first captured and handled by the innermost
element and then propagated to outer elements. The execution starts from that event
and goes to its parent element.
Then the execution passes to its parent element and so on till the body element.

Ques: What is NaN in JavaScript?


Ans NaN is a short form of Not a Number. Since NaN always compares unequal to any
number, including NaN, it is usually used to indicate
an error condition for a function that should return a valid number. When a string
or something else is being converted into a number
and that cannot be done, then we get to see NaN.

Ques: How do JavaScript primitive/object types passed in functions?


Ans: One of the differences between the two is that Primitive Data Types are passed
By Value and Objects are passed By Reference.

Ques: How can you convert the string of any base to integer in JavaScript?
Ans: The parseInt() function is used to convert numbers between different bases. It
takes the string to be converted as its first parameter,
and the second parameter is the base of the given string.
For example- parseInt("4F", 16)

Ques: What would be the result of 2+5+”3″?


Ans: Since 2 and 5 are integers, they will be added numerically. And since 3 is a
string, its concatenation will be done.
So the result would be 73. The ” ” makes all the difference here and represents 3
as a string and not a number.

Ques: What will be the output of the code below?


Ans: var Y = 1;
if (function F(){})
{
y += Typeof F;</span>
}
console.log(y);
The output would be 1undefined. The if condition statement evaluates using eval, so
eval(function f(){}) returns function f(){} (which is true).
Therefore, inside the if statement, executing typeof f returns undefined because
the if statement code executes at run time, and the
statement inside the if condition is evaluated during run time.

Ques: How to empty an Array in JavaScript?


Ans: There are a number of methods you can use to empty an array:
1. arrayList = []
2. arrayList.length = 0;
3. arrayList.splice(0, arrayList.length);
4. while(arrayList.length)
{
arrayList.pop();
}

Ques: What will be the output of the following code?


Ans: var Output = (function(x)
{
Delete X;
return X;
}
)(0);
console.log(output);
The output would be 0. The delete operator is used to delete properties from an
object. Here x is not an object but a local variable.
delete operators don’t affect local variables.

Ques: What will be the output of the following code?


Ans: var X = { Foo : 1};
var Output = (function()
{
delete X.foo;
return X.foo;
}
)();
console.log(output);
The output would be undefined. The delete operator is used to delete the property
of an object. Here, x is an object which has the
property foo, and as it is a self-invoking function, we will delete the foo
property from object x. After doing so, when we try
to reference a deleted property foo, the result is undefined.

Ques: What will be the output of the following code?


Ans: var Employee =
{
company: 'xyz'
}
var Emp1 = Object.create(employee);
delete Emp1.company Console.log(emp1.company);
The output would be xyz. Here, emp1 object has company as its prototype property.
The delete operator doesn’t delete prototype property.
emp1 object doesn’t have company as its own property. However, we can delete the
company property directly from the Employee object using delete Employee.company.

Ques: What will be the output of the code below?


Ans: //nfe (named function expression)
var Foo = Function Bar()
{
return 7;
};
typeof Bar();
The output would be Reference Error. A function definition can have only one
reference variable as its function name.

Ques: Diff between asynch paraller and series


Ans: Async Utility Module
Async is a utility module which provides straight-forward, powerful functions for
working with asynchronous JavaScript. Although it is built on top of promises, it
makes asynchronous code look and behave a little more like synchronous code, making
it easier to read and maintain.

Async utility has a number of control flows. Let’s discuss the most popular ones
and their use cases:

1. Parallel
When we have to run multiple tasks independent of each other without waiting until
the previous task has completed, parallel comes into the picture.

async.parallel(tasks, callback)
view rawparallel.js hosted with ❤ by GitHub
Tasks: A collection of functions to run. It can be an array, an object or any
iterable.

Callback: This is the callback where all the task results are passed and is
executed once all the task execution has completed.

In case an error is passed to a function's callback, the main callback is


immediately called with the error. Although parallel is about starting I/O tasks in
parallel, it’s not about parallel execution since Javascript is single-threaded.

An example of Parallel is shared below:

async.parallel([
function(callback) {
setTimeout(function() {
console.log('Task One');
callback(null, 1);
}, 200);
},
function(callback) {
setTimeout(function() {
console.log('Task Two');
callback(null, 2);
}, 100);
}
],
function(err, results) {
console.log(results);
// the results array will equal [1, 2] even though
// the second function had a shorter timeout.
});

// an example using an object instead of an array


async.parallel({
task1: function(callback) {
setTimeout(function() {
console.log('Task One');
callback(null, 1);
}, 200);
},
task2: function(callback) {
setTimeout(function() {
console.log('Task Two');
callback(null, 2);
}, 100);
}
}, function(err, results) {
console.log(results);
// results now equals to: { task1: 1, task2: 2 }
});
view rawasync-parallel-example.js hosted with ❤ by GitHub
2. Series
When we have to run multiple tasks which depend on the output of the previous task,
series comes to our rescue.

async.series(tasks, callback)
view rawseries.js hosted with ❤ by GitHub
Tasks: A collection of functions to run. It can be an array, an object or any
iterable.

Callback: This is the callback where all the task results are passed and is
executed once all the task execution has completed.

Callback function receives an array of result objects when all the tasks have been
completed. If an error is encountered in any of the task, no more functions are run
but the final callback is called with the error value.

An example of Series is shared below:

async.series([
function(callback) {
console.log('one');
callback(null, 1);
},
function(callback) {
console.log('two');
callback(null, 2);
},
function(callback) {
console.log('three');
callback(null, 3);
}
],
function(err, results) {
console.log(result);
// results is now equal to [1, 2, 3]
});

async.series({
1: function(callback) {
setTimeout(function() {
console.log('Task 1');
callback(null, 'one');
}, 200);
},
2: function(callback) {
setTimeout(function() {
console.log('Task 2');
callback(null, 'two');
}, 300);
},
3: function(callback) {
setTimeout(function() {
console.log('Task 3');
callback(null, 'three');
}, 100);
}
},
function(err, results) {
console.log(results);
// results is now equal to: { 1: 'one', 2: 'two', 3:'three' }
});
view rawasyn-series-example.js hosted with ❤ by GitHub
3. Waterfall
When we have to run multiple tasks which depend on the output of previous task,
Waterfall can be helpful.

async.waterfall(tasks, callback)
view rawwaterfall.js hosted with ❤ by GitHub
Tasks: A collection of functions to run. It can be an array, an object or any
iterable structure.

Callback: This is the callback where all the task results are passed and is
executed once all the task execution has completed.

It will run one function at a time and pass the result of the previous function to
the next one.

An example of Waterfall is shared below:

async.waterfall([
function(callback) {
callback(null, 'Task 1', 'Task 2');
},
function(arg1, arg2, callback) {
// arg1 now equals 'Task 1' and arg2 now equals 'Task 2'
let arg3 = arg1 + ' and ' + arg2;
callback(null, arg3);
},
function(arg1, callback) {
// arg1 now equals 'Task1 and Task2'
arg1 += ' completed';
callback(null, arg1);
}
], function(err, result) {
// result now equals to 'Task1 and Task2 completed'
console.log(result);
});

// Or, with named functions:


async.waterfall([
myFirstFunction,
mySecondFunction,
myLastFunction,
], function(err, result) {
// result now equals 'Task1 and Task2 completed'
console.log(result);
});

function myFirstFunction(callback) {
callback(null, 'Task 1', 'Task 2');
}
function mySecondFunction(arg1, arg2, callback) {
// arg1 now equals 'Task 1' and arg2 now equals 'Task 2'
let arg3 = arg1 + ' and ' + arg2;
callback(null, arg3);
}
function myLastFunction(arg1, callback) {
// arg1 now equals 'Task1 and Task2'
arg1 += ' completed';
callback(null, arg1);
}
view rawasync-waterfall-example.js hosted with ❤ by GitHub
4. Queue
When we need to run a set of tasks asynchronously, queue can be used. A queue
object based on an asynchronous function can be created which is passed as worker.

async.queue(task, concurrency)
view rawqueue.js hosted with ❤ by GitHub
Task: Here, it takes two parameters, first - the task to be performed and second -
the callback function.

Concurrency: It is the number of functions to be run in parallel.

async.queue returns a queue object that supports few properties:

push: Adds tasks to the queue to be processed.


drain: The drain function is called after the last task of the queue.
unshift: Adds tasks in front of the queue.
An example of Queue is shared below:

// create a queue object with concurrency 2


var q = async.queue(function(task, callback) {
console.log('Hello ' + task.name);
callback();
}, 2);
// assign a callback
q.drain = function() {
console.log('All items have been processed');
};

// add some items to the queue


q.push({name: 'foo'}, function(err) {
console.log('Finished processing foo');
});

q.push({name: 'bar'}, function (err) {


console.log('Finished processing bar');
});

// add some items to the queue (batch-wise)


q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
console.log('Finished processing item');
});

// add some items to the front of the queue


q.unshift({name: 'bar'}, function (err) {
console.log('Finished processing bar');
});
view rawasync-queue-example.js hosted with ❤ by GitHub
5. Priority Queue
It is the same as queue, the only difference being that a priority can be assigned
to the tasks which is considered in ascending order.

async.priorityQueue(task,concurrency)
view rawpriority_queue.js hosted with ❤ by GitHub
Task: Here, it takes three parameters:

First - task to be performed.


Second - priority, it is a number that determines the sequence of execution. For
array of tasks, the priority remains same for all of them.
Third - Callback function.

The async.priorityQueue does not support ‘unshift’ property of the queue.

An example of Priority Queue is shared below:

// create a queue object with concurrency 1


var q = async.priorityQueue(function(task, callback) {
console.log('Hello ' + task.name);
callback();
}, 1);

// assign a callback
q.drain = function() {
console.log('All items have been processed');
};

// add some items to the queue with priority


q.push({name: 'foo'}, 3, function(err) {
console.log('Finished processing foo');
});

q.push({name: 'bar'}, 2, function (err) {


console.log('Finished processing bar');
});

// add some items to the queue (batch-wise) which will have same priority
q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], 1, function(err) {
console.log('Finished processing item');
});
view rawasync-priorityQueue-example.js hosted with ❤ by GitHub
6. Race
It runs all the tasks in parallel, but as soon as any of the function completes its
execution or passes error to its callback, the main callback is immediately called.

async.race(tasks, callback)
view rawrace.js hosted with ❤ by GitHub
Task: Here, it is a collection of functions to run. It is an array or any iterable.

Callback: The result of the first complete execution is passed. It may be the
result or error.

An example of Race is shared below:

async.race([
function (callback) {
setTimeout(function () {
callback(null, 'one');
}, 300);
},
function (callback) {
setTimeout(function () {
callback(null, 'two');
}, 100);
},
function (callback) {
setTimeout(function () {
callback(null, 'three');
}, 200);
}
],
// main callback
function (err, result) {
// the result will be equal to 'two' as it finishes earlier than the other 2
console.log('The result is ', result);
});
view rawasync-race-example.js hosted with ❤ by GitHub
Combining Async Flows
In complex scenarios, the async flows like parallel and series can be combined and
nested. This helps in achieving the expected output with the benefits of async
utilities.

However, the only difference between Waterfall and Series async utility is that the
final callback in series receives an array of results of all the task whereas in
Waterfall, the result object of the final task is received by the final callback.

Ques: Diff between promise.all and promise.allsettled


Ans: Promise.all():
Promise.all() resolves only when all given promises resolve, and will reject
immediately if any of the promises reject (or non-promises throw an error). It is
useful in cases when you have interdependent tasks, where it makes sense to reject
immediately upon any of them rejecting.
Promise.allSettled():
Promise.allSettled() resolves when all of the given promises have either fulfilled
or rejected. Unlike Promise.all(), it does not immediately reject upon any of the
promises rejecting, instead it waits for all promises to complete, even if some of
them fail. Therefore, it is useful in cases when you have multiple asynchronous
tasks that are not interdependent, where you may want to know the result of each
promise.

Difference in Return Value


Promise.all():
Promise.all() returns a single Promise that resolves to an array of the results of
all given promises. For example:

const p1 = Promise.resolve(1);
const p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2, 'foo');
});
const p3 = 3;

Promise.all([p1, p2, p3])


.then((values) => console.log(values)); // [1, 'foo', 3]
In case any of the promises fail, Promise.all() rejects with the value of the
promise that rejected (regardless of whether or not the other promises have
resolved).

const p1 = Promise.resolve(1);
const p2 = Promise.reject('foo');
const p3 = 3;

Promise.all([p1, p2, p3])


.then((values) => console.log(values))
.catch((err) => console.log(err)); // 'foo'
Promise.allSettled():
Promise.allSettled() returns an array of objects that describes the outcome of each
promise. Depending on whether the promises were resolved or rejected, the resulting
array of objects each contains a status string. If the status is "fulfilled", then
a value property is present, or if the status is "rejected", then a reason property
is present. For example:

const p1 = Promise.resolve(1);
const p2 = Promise.reject('foo');
const p3 = 3;

Promise.allSettled([p1, p2, p3])


.then((values) => console.log(values));

/* [
{ status: 'fulfilled', value: 1 },
{ status: 'rejected', reason: 'foo' },
{ status: 'fulfilled', value: 3 },
] */

Ques: Node.js Global Objects


Ans: Node.js Global Objects are the objects that are available in all modules.
Global Objects are built-in objects that are part of the JavaScript and can be used
directly in the application without importing any particular module. The Node.js
Global Objects are listed below:

1.Class: Buffer The Buffer class is an inbuilt globally accessible class that means
it can be used without importing any module. The Buffer class is used to deal with
binary data. Buffer class objects are used to represent binary data as a sequence
of bytes.
const buffer = new Buffer(5,'abcde');
console.log(buffer)
O/p => Buffer 61 62 63 64 65

console: It is an inbuilt global object used to print to stdout and stderr.


console.error('An error occured');

process: It is an inbuilt global object that is an instance of EventEmitter used to


get information on current process. It can also be accessed using require()
explicitly.

global: It is a global namespace. Defining a variable within this namespace makes


it globally accessible.
var myvar

2.It is a global scope when declared within the browser. However, any variable
defined within a node.js file is accessible only within that file.

setImmediate() method: It schedules the immediate execution of the callback. The


callback functions are queued and executed in the order in which they are created.
The callback queue is processed at every event loop iteration. If there is a timer
queued inside the executing callback, the timer will not get triggered until the
next event loop iteration.
clearImmediate() method: It stops the immediate object returned by the
setImmediate() method.
setInterval() method: It executes the callback function at repeated intervals. If
an interval is larger than 2147483647 or less than 1, the interval is set to 1.
Non-integer delays are truncated to the nearest integer.
clearInterval() method: It stops the interval object created by setInterval()
method.

setTimeout() method: It is a global function used to run a callback function after


at least delay in milliseconds. Node.js does not guarantee the exact timing of when
callbacks will fire but tries to maintain the timing as close as possible to the
specified delay. Any delay larger than 2147483647 or less than 1, is set to 1
automatically. Non-integer delays are truncated to the nearest integer.

function printHello() {
console.log( "Hello, World!");
}

// Now call above function after 2 seconds


var timeoutObj = setTimeout(printHello, 2000);

clearTimeout() method: The clearTimeout() method is used to cancel or stop a


timeout that was set with setTimeout() method. The timeoutObj is the object
returned by setTimeout() method.

queueMicrotask() method: A microtask is a short function that is executed after the


callback function exits and only if the JavaScript execution stack is empty. The
queueMicrotask() method is used to execute such functions after the callback
function completes successfully. If the callback function does not return the
control to other JavaScript code, the event loop runs all of the microtasks in the
microtask queue. The microtask queue is processed multiple times per iteration of
the event loop. If a microtask adds more microtasks to the queue then the newly-
added microtasks execute before the next task is run. This is because the event
loop keeps calling microtasks until there are none left in the queue.
TextEncoder: It is an implementation of the WHATWG Encoding Standard TextEncoder
API. All instances of TextEncoder are encoded in UTF-8 only.

const encoder = new TextEncoder();


const e = encoder.encode('Welcome to GFG');
console.log(e);
uInt8Array [
87, 101, 108, 99, 111,
109, 111, 32, 116, 111,
32, 71, 70, 71
];

3.TextDecoder: It is an implementation of the WHATWG Encoding Standard TextDecoder


API.

4.Class: URL The URL class instance is a global object and is implemented by the
following WHATWG URL Standard. The URL constructor creates a new URL object as
shown below. /foo is the input and https://www.helloworld.og/ is the base value.

const url = new URL("/foo", "https://www.helloworld.og/");


console.log(url);

5.URLSearchParams: URLSearchParams API is used to perform read and write operations


on the query of a URL.
const myURL = new URL('https://www.register.com/?name=gfg');

// It prints gfg
console.log(myURL.searchParams.get('name'));

myURL.searchParams.append('name', 'xyz');

// It prints https://www.register.com/?name=gfg&name=xyz
console.log(myURL.href);
6.WebAssembly: The global object that acts as a namespace for all W3C WebAssembly
related functionality. WebAssembly is a low level Assembly-like language that can
be run on modern browsers.

The following variables might appear to be global but actually exist only within
the scope of some modules.

> require(id) method: It is used to import modules and returns an object of ‘any’
datatype.
var express = require('express')
> exports: It is used to exports modules using module.exports.
> module: It is a reference to the current module and is not global rather local to
each module. It is used to make a particular module available through require() in
the application.

> __dirname: The output throws an error which proves that __dirname is not globally
defined in node.js. It requires a script to give the desired output as __dirname is
only defined in scripts.
Create a demo.js file
Paste the following code:
console.log("__dirname : "+ __dirname);
Run the demo.js file
7.__filename: The output throws an error which proves that __dirname is not
globally defined in node.js. It requires a script to give the desired output as
__filename is only defined in scripts.
Create a demo.js file
Paste the following code:
console.log("__filename : "+ __filename);
Run the demo.js file

//some extra
Value of this in a node module:
this in NodeJS global scope is the current module.exports object, not the global
object. This is different from a browser where the global scope is the global
window object. Consider the following code executed in Node:

console.log(this); // logs {}

module.exports.foo = 5;

console.log(this); // log { foo:5 }


First we log an empty object because there are no values in module.exports in this
module. Then we put foo on the module.exports object, when we then again log this
we can see that it now logs the updated module.exports object.

How can we access the global object:


We can access the global object in node using the global keyword:

console.log(global);
The global object exposes a variety of useful properties about the environment.
Also this is the place where functions as setImmediate and clearTimeout are
located.

Ques: Routing in express.


Ans: var express = require('express')
var app = express()

// respond with "hello world" when a GET request is made to the homepage
app.get('/', function (req, res) {
res.send('hello world')
})

Route path: /users/:userId/books/:bookId


Request URL: http://localhost:3000/users/34/books/8989
req.params: { "userId": "34", "bookId": "8989" }
To define routes with route parameters, simply specify the route parameters in the
path of the route as shown below.

app.get('/users/:userId/books/:bookId', function (req, res) {


res.send(req.params)
})

Here is an example of chained route handlers that are defined by using app.route().

app.route('/book')
.get(function (req, res) {
res.send('Get a random book')
})
.post(function (req, res) {
res.send('Add a book')
})
.put(function (req, res) {
res.send('Update the book')
})

express.Router
Use the express.Router class to create modular, mountable route handlers. A Router
instance is a complete middleware and routing system; for this reason, it is often
referred to as a “mini-app”.

The following example creates a router as a module, loads a middleware function in


it, defines some routes, and mounts the router module on a path in the main app.

Create a router file named birds.js in the app directory, with the following
content:

var express = require('express')


var router = express.Router()

// middleware that is specific to this router


router.use(function timeLog (req, res, next) {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', function (req, res) {
res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
res.send('About birds')
})

module.exports = router
Then, load the router module in the app:

var birds = require('./birds')

// ...

app.use('/birds', birds)

Ques: middleware in node JS


Ans: Middleware functions are functions that have access to the request object
(req), the response object (res), and the next middleware function in the
application’s request-response cycle. The next middleware function is commonly
denoted by a variable named next.

Middleware functions can perform the following tasks:

Execute any code.


Make changes to the request and the response objects.
End the request-response cycle.
Call the next middleware function in the stack.
If the current middleware function does not end the request-response cycle, it must
call next() to pass control to the next middleware function. Otherwise, the request
will be left hanging.

An Express application can use the following types of middleware:


Application-level middleware
Router-level middleware
Error-handling middleware
Built-in middleware
Third-party middleware
You can load application-level and router-level middleware with an optional mount
path. You can also load a series of middleware functions together, which creates a
sub-stack of the middleware system at a mount point.

Application-level middleware
Bind application-level middleware to an instance of the app object by using the
app.use() and app.METHOD() functions, where METHOD is the HTTP method of the
request that the middleware function handles (such as GET, PUT, or POST) in
lowercase.

This example shows a middleware function with no mount path. The function is
executed every time the app receives a request.

var express = require('express')


var app = express()

app.use(function (req, res, next) {


console.log('Time:', Date.now())
next()
})
This example shows a middleware function mounted on the /user/:id path. The
function is executed for any type of HTTP request on the /user/:id path.

app.use('/user/:id', function (req, res, next) {


console.log('Request Type:', req.method)
next()
})
This example shows a route and its handler function (middleware system). The
function handles GET requests to the /user/:id path.

app.get('/user/:id', function (req, res, next) {


res.send('USER')
})
Here is an example of loading a series of middleware functions at a mount point,
with a mount path. It illustrates a middleware sub-stack that prints request info
for any type of HTTP request to the /user/:id path.

app.use('/user/:id', function (req, res, next) {


console.log('Request URL:', req.originalUrl)
next()
}, function (req, res, next) {
console.log('Request Type:', req.method)
next()
})
Route handlers enable you to define multiple routes for a path. The example below
defines two routes for GET requests to the /user/:id path. The second route will
not cause any problems, but it will never get called because the first route ends
the request-response cycle.

This example shows a middleware sub-stack that handles GET requests to the
/user/:id path.

app.get('/user/:id', function (req, res, next) {


console.log('ID:', req.params.id)
next()
}, function (req, res, next) {
res.send('User Info')
})

// handler for the /user/:id path, which prints the user ID


app.get('/user/:id', function (req, res, next) {
res.send(req.params.id)
})
To skip the rest of the middleware functions from a router middleware stack, call
next('route') to pass control to the next route. NOTE: next('route') will work only
in middleware functions that were loaded by using the app.METHOD() or
router.METHOD() functions.

This example shows a middleware sub-stack that handles GET requests to the
/user/:id path.

app.get('/user/:id', function (req, res, next) {


// if the user ID is 0, skip to the next route
if (req.params.id === '0') next('route')
// otherwise pass the control to the next middleware function in this stack
else next()
}, function (req, res, next) {
// send a regular response
res.send('regular')
})

// handler for the /user/:id path, which sends a special response


app.get('/user/:id', function (req, res, next) {
res.send('special')
})
Middleware can also be declared in an array for reusability.

This example shows an array with a middleware sub-stack that handles GET requests
to the /user/:id path

function logOriginalUrl (req, res, next) {


console.log('Request URL:', req.originalUrl)
next()
}

function logMethod (req, res, next) {


console.log('Request Type:', req.method)
next()
}

var logStuff = [logOriginalUrl, logMethod]


app.get('/user/:id', logStuff, function (req, res, next) {
res.send('User Info')
})

Router-level middleware
Router-level middleware works in the same way as application-level middleware,
except it is bound to an instance of express.Router().

var router = express.Router()


Load router-level middleware by using the router.use() and router.METHOD()
functions.

The following example code replicates the middleware system that is shown above for
application-level middleware, by using router-level middleware:

var express = require('express')


var app = express()
var router = express.Router()

// a middleware function with no mount path. This code is executed for every
request to the router
router.use(function (req, res, next) {
console.log('Time:', Date.now())
next()
})

// a middleware sub-stack shows request info for any type of HTTP request to the
/user/:id path
router.use('/user/:id', function (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()
}, function (req, res, next) {
console.log('Request Type:', req.method)
next()
})

// a middleware sub-stack that handles GET requests to the /user/:id path


router.get('/user/:id', function (req, res, next) {
// if the user ID is 0, skip to the next router
if (req.params.id === '0') next('route')
// otherwise pass control to the next middleware function in this stack
else next()
}, function (req, res, next) {
// render a regular page
res.render('regular')
})

// handler for the /user/:id path, which renders a special page


router.get('/user/:id', function (req, res, next) {
console.log(req.params.id)
res.render('special')
})

// mount the router on the app


app.use('/', router)
To skip the rest of the router’s middleware functions, call next('router') to pass
control back out of the router instance.

This example shows a middleware sub-stack that handles GET requests to the
/user/:id path.

var express = require('express')


var app = express()
var router = express.Router()

// predicate the router with a check and bail out when needed
router.use(function (req, res, next) {
if (!req.headers['x-auth']) return next('router')
next()
})

router.get('/user/:id', function (req, res) {


res.send('hello, user!')
})

// use the router and 401 anything falling through


app.use('/admin', router, function (req, res) {
res.sendStatus(401)
})

Error-handling middleware
Error-handling middleware always takes four arguments. You must provide four
arguments to identify it as an error-handling middleware function. Even if you
don’t need to use the next object, you must specify it to maintain the signature.
Otherwise, the next object will be interpreted as regular middleware and will fail
to handle errors.

Define error-handling middleware functions in the same way as other middleware


functions, except with four arguments instead of three, specifically with the
signature (err, req, res, next)):

app.use(function (err, req, res, next) {


console.error(err.stack)
res.status(500).send('Something broke!')
})

Ques: Event-Driven Programming in Node.js


Ans: Event-Driven Programming in Node.js: Node.js makes extensive use of events
which is one of the reasons behind its speed when compared to other similar
technologies. Once we start a Node.js server, it initializes the variables and
functions and then listens for the occurrence of an event.

Event-driven programming is used to synchronize the occurrence of multiple events


and to make the program as simple as possible. The basic components of an Event-
Driven Program are:

A callback function ( called an event handler) is called when an event is


triggered.
An event loop that listens for event triggers and calls the corresponding event
handler for that event.

A function that listens for the triggering of an event is said to be an ‘Observer’.


It gets triggered when an event occurs. Node.js provides a range of events that are
already in-built. These ‘events’ can be accessed via the ‘events’ module and the
EventEmitter class. Most of the in-built modules of Node.js inherit from the
EventEmitter class

EventEmitter: The EventEmitter is a Node module that allows objects to communicate


with one another. The core of Node’s asynchronous event-driven architecture is
EventEmitter. Many of Node’s built-in modules inherit from EventEmitter.

The idea is simple – emitter objects send out named events, which trigger listeners
that have already been registered. Hence, an emitter object has two key
characteristics:

Emitting name events: The signal that something has happened is called emitting an
event. A status change in the emitting object is often the cause of this condition.
Registering and unregistering listener functions: It refers to the binding and
unbinding of the callback functions with their corresponding events.
Event-Driven Programming Principles:

A suite of functions for handling the events. These can be either blocking or non-
blocking, depending on the implementation.
Binding registered functions to events.
When a registered event is received, an event loop polls for new events and calls
the matching event handler(s).

// Import the 'events' module


const events = require('events');

// Instantiate an EventEmitter object


const eventEmitter = new events.EventEmitter();

// Handler associated with the event


const connectHandler = function connected() {
console.log('Connection established.');

// Trigger the corresponding event


eventEmitter.emit('data_received');
}

// Binds the event with handler


eventEmitter.on('connection', connectHandler);

// Binds the data received


eventEmitter.on(
'data_received', function () {
console.log('Data Transfer Successful.');
});

// Trigger the connection event


eventEmitter.emit('connection');

console.log("Finish");

The above code snippet binds the handler named ‘connectHandler’ with the event
‘connection’’. The callback function is triggered when the event is emitted.

Run the app.js file using the following command:

node app.js
Output:

Connection established.
Data Transfer Successful.
Finish

Ques: Difference between npm and yarn


Ans: npm: It is a package manager for the JavaScript programming language. It is
the default package manager for the JavaScript runtime environment Node.js. It
consists of a command-line client, also called npm, and an online database of
public and paid-for private packages called the npm registry.
yarn: It stands for Yet Another Resource Negotiator and it is a package manager
just like npm. It was developed by Facebook and is now open-source. The intention
behind developing yarn(at that time) was to fix performance and security concerns
with npm.

The differences between npm and yarn are explained below:


Installation procedure
npm: npm is installed with Node automatically.
yarn: To install yarn npm have to be installed.
npm install yarn --global

The lock file

npm: NPM generates a ‘package-lock.json’ file. The package-lock.json file is a


little more complex due to a trade-off between determinism and simplicity. Due to
this complexity, the package-lock will generate the same node_modules folder for
different npm versions. Every dependency will have an exact version number
associated with it in the package-lock file.
yarn: Yarn generates a ‘yarn.lock’ file. Yarn lock files help in easy merge. The
merges are predictable as well, because of the design of the lock file.

Output log
npm
install: The npm creates massive output logs of npm commands. It is essentially a
dump of stack trace of what npm is doing.
yarn
add: The yarn output logs are clean, visually distinguishable and brief. They are
also ordered in a tree form for understandability.

Installing global dependencies

npm: To install a global package, the command template for npm is:
npm install -g package_name@version_number
yarn: To install a global package, the command template for yarn is:
yarn global add package_name@version_number

The ‘why’ command:


npm: npm yet doesn’t has a ‘why’ functionality built in.
yarn: Yarn comes with a ‘why’ command that tells why a dependency is present in the
project. For example, it is a dependency, a native module, or a project dependency.

License Checker
npm: npm doesn’t has a license checker that can give a handy description of all the
licenses that a project is bound with, due to installed dependencies.
yarn: Yarn has a neat license checker. To see them, run
yarn licenses list

Fetching packages

npm: npm fetches dependencies from the npm registry during every ‘npm install‘
command.
Yarn: yarn stores dependencies locally, and fetches from the disk during a ‘yarn
add‘ command (assuming the dependency(with the specific version) is present
locally).
Ques: Node.js | package.json
The package.json file is the heart of Node.js system. It is the manifest file of
any Node.js project and contains the metadata of the project. The package.json file
is the essential part to understand, learn and work with the Node.js. It is the
first step to learn about developmnent in Node.js.

What does package.json file consist of?


The metadata information in package.json file can be categorized into below
categories:
1. Identifying metadata properties: It basically consist of the properties to
identify the module/project such as the name of the project, current version of the
module, license, author of the project, description about the project etc.
2. Functional metadata properties: As the name suggests, it consists of the
functional values/properties of the project/module such as the entry/starting point
of the module, dependencies in project, scripts being used, repository links of
Node project etc.

Creating a package.json file:


A package.json file can be created in two ways:
1. Using npm init : Running this command, system expects user to fill the vital
information required as discussed above. It provides users with default values
which are editable by the user.
Syntax:

npm init
2. Writing directly to file : One can directly write into file with all the
required information and can include it in the Node project.

Example: A demo package.json file with the required information.


{
"name": "GeeksForGeeks",
"version": "1.0.0",
"description": "GeeksForGeeks",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node start.js",
},
"engines": {
"node": ">=7.6.0",
"npm": ">=4.1.2"
},
"author": "GeeksForGeeks",
"license": "ISC",
"dependencies": {
"body-parser": "^1.17.1",
"express": "^4.15.2",
"express-validator": "^3.1.2",
"mongoose": "^4.8.7",
"nodemon": "^1.14.12",
},
"devDependencies": {},
"repository": {
"type": "git",
"url": "https://github.com/gfg/gfg.git" //sample git repo url
},
"bugs": {
"url": "https://github.com/gfg/gfg/issues"
},
"homepage": "https://github.com/gfg/gfg#readme"
}
Explanation:
name: The name of the application/project.
version: The version of application. The version should follow semantic versioning
rules.
description: The description about the application, purpose of the application,
technology used like React, MongoDB, etc.
main: This is the entry/starting point of the app. It specifies the main file of
the application that triggers when the application starts. Application can be
started using npm start.
scripts: The scripts which needs to be included in the application to run properly.
engines: The versions of the node and npm used. These versions are specified in
case the application is deployed on cloud like heroku or google-cloud.
keywords: It specifies the array of strings that characterizes the application.
author: It consist of the information about the author like name, email and other
author related information.
license: The license to which the application confirms are mentioned in this key-
value pair.
dependencies: The third party package or modules installed using npm are specified
in this segment.
devDependencies: The dependencies that are used only in the development part of the
application are specified in this segment. These dependencies do not get rolled out
when the application is in production stage.
repository: It contain the information about the type and url of the repository
where the code of the application lives is mentioned here in this segment.
bugs: The url and email where the bugs in the application should be reported are
mentioned in this segment.

Note: Here, “body-parser”, “express”, “express-validator”, “mongoose” and “nodemon”


are the modules/packages installed using npm (Node Package Manager).

Ques: Difference between dependencies, devDependencies and peerDependencies


Ans: Dependencies: In package.json file, there is an object called dependencies and
it consists of all the packages that are used in the project with its version
number. So, whenever you install any library that is required in your project that
library you can find it in the dependencies object.

Syntax: npm install <package name>


Example: Installing the moment module for formatting the time in the project using
the following command:
npm install moment
After the module is installed, then if you navigate to the package.json file then
you can find the moment with its version in the dependencies object as shown below:
"dependencies" : {
"moment": "^2.23.0"
}

Dev Dependencies: In package.json file, there is an object called as dev


Dependencies and it consists of all the packages that are used in the project in
its development phase and not in the production or testing environment with its
version number. So, whenever you want to install any library that is required only
in your development phase then you can find it in the dev Dependencies object.
npm install <package name> --save-dev
Example: Installing the bootstrap module that we want to use in the development
phase only and not in the production or testing phase for the project, use the
following command:
npm install bootstrap --save-dev
After completion of the download, then if you navigate to the package.json file
then you can find the bootstrap with its version in the dev Dependencies object as
shown below:
"devDependencies" : {
"bootstrap": "^2.23.0"
}

Peer Dependencies: In package.json file, there is an object called as


peerDependencies and it consists of all the packages that are exactly required in
the project or to the person who is downloading and the version numbers should also
be the same. That is the reason they were named as peerDependencies. The best
example is ‘react’ which is common in every project to run similarly.

When you install an npm package using npm install <package-name>, you are
installing it as a dependency.

The package is automatically listed in the package.json file, under the


dependencies list (as of npm 5: before you had to manually specify --save).

When you add the -D flag, or --save-dev, you are installing it as a development
dependency, which adds it to the devDependencies list.

Development dependencies are intended as development-only packages, that are


unneeded in production. For example testing packages, webpack or Babel.

When you go in production, if you type npm install and the folder contains a
package.json file, they are installed, as npm assumes this is a development deploy.

You need to set the --production flag (npm install --production) to avoid
installing those development dependencies.

Ques: What is LTS


Ans: Release Terminology
Current: Current is a term used to refer to the most recent Node.js release line
(yes, that's singular) that will be supported and open to non-trivial changes until
the next major release.
LTS: LTS is an acronym for Long-Term Support, and is applied to release lines (yes,
that's plural) that will be supported and maintained by the Node.js project for an
extended period of time.
Active: An Active LTS release line is one that is being actively maintained and
upgraded, including backporting newer non-breaking features, functionality, and
improvements, addressing bugs, and patching security vulnerabilities.
Maintenance: A Maintenance LTS release line is a Node.js LTS release line that's
nearing End of Life (EOL) and will only receive bug fixes and security patches for
a short window of time.
EOL: EOL is an acronym for End of Life. Node.js versions that are EOL are no longer
maintained, and will not be patched with fixes for bugs or known security
vulnerabilities.
Cutting/Shipping: Cutting and shipping are both terms used to refer to the actual
release of any given version (major, minor, or patch) of Node.js. These terms
aren't specific to Node.js but are used relatively often by the Node.js contributor
base.

Ques: Subprocesses in node Js or Node.js Child Process


Ans: Usually, Node.js allows single-threaded, non-blocking performance but running
a single thread in a CPU cannot handle increasing workload hence the child_process
module can be used to spawn child processes. The child processes communicate with
each other using a built-in messaging system.

The following are the four different ways to create a child process in Node.js:

spawn() method
fork() method
exec() method
execFile() method
Above mentioned ways are explained below:

1) spawn() method: This method spawns a new process using the given command and the
command line arguments in args. The ChildProcess instance implements
EventEmitterAPI which enables us to register handlers for events on child object
directly. Some events that can be registered for handling with the ChildProcess are
exit, disconnect, error, close and message.
Syntax:

child_process.spawn(command[, args][, options])


Parameters:
command: Accepts a string which is the command to run.
args: List of string arguments. Default value is an empty array.
options:
shell: Accepts a boolean value. If true, runs command inside of a shell. Different
shell can be specified as a string. Default value is false which implies no shell.
By default, spawn() does not create a shell to execute the command hence it is
important to pass it as option while invoking the child process.
Additional options such as cwd, env, argv0, stdio etc can be used as per
requirement.

Return Value: Returns a ChildProcess object.

Example:
const { spawn } = require('child_process');
const child = spawn('dir', ['D:\Test'], {shell: true});
child.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});

child.stderr.on('data', (data) => {


console.error(`stderr: ${data}`);
});

child.on('close', (code) => {


console.log(`child process exited with code ${code}`);
});

2) fork() method: The child_process.fork() is a special case of


child_process.spawn() where the parent and the child process can communicate with
each other via send(). The fork() allows separation of computation-intensive tasks
from the main event loop. Child processes are independent of the parent except the
IPC communication channel established between them. Each process has its own
memory, therefore invoking a large number of child processes can affect the
performance of the application. The shell option is not supported by
child_process.fork().

Syntax:
child_process.fork(modulePath[, args][, options])
Parameters:

modulePath: Accepts a string that specifies the module to run in the child.
args: List of string arguments.
options: cwd, detached, env, execPath, execArgv are some of the available options
for this method.
Return Value: Returns a ChildProcess instance.

Example: Filename: fork.js


// Write Javascript code here
var cp = require('child_process');

var child = cp.fork(__dirname + '/sub.js');

child.on('message', function(m) {
console.log('Parent process received:', m);
});

child.send({ hello: 'from parent process' });

child.on('close', (code) => {


console.log(`child process exited with code ${code}`);
});

Filename: sub.js
process.on('message', function(m) {
console.log('Child process received:', m);
});

process.send({ hello: 'from child process' });

Output:
Parent process received: { hello: 'from child process' }
Child process received: {hello: 'from parent process'}

3) exec() method: This method creates a shell first and then executes the command.

Syntax:

child_process.exec(command[, options][, callback])


Parameters:

command: Accepts a string that specifies the command to run with space-separated
arguments.
options: Some of the options available are cwd, env, encoding, shell, timeout etc
callback: The callback function is called when process terminates. The arguments to
this function are error, stdout and stderr respectively.
Return Value: Returns an instance of ChildProcess.

Example:
const { exec } = require('child_process');

// Counts the number of directory in


// current working directory
exec('dir | find /c /v ""', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: No. of directories = ${stdout}`);
if (stderr!= "")
console.error(`stderr: ${stderr}`);
});
Output:
No. of directories = 60

4) execFile() method: The child_process.execFile() function is does not spawn a


shell by default. It is slightly more efficient than child_process.exec() as the
specified executable file is spawned directly as a new process.

Syntax:

child_process.execFile(file[, args][, options][, callback])


Parameters:

file: Accepts a string that specifies the name or path of the file to run.
args: List of string arguments.
options: Some of the options available are cwd, env, encoding, shell, timeout etc
callback: The callback function is called when process terminates. The arguments to
this function are error, stdout and stderr respectively.
Return Value: Returns an instance of ChildProcess.
const { execFile } = require('child_process');

// Executes the exec.js file


const child = execFile('node', ['exec.js'],
(error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
Output:
From exec.js file
stdout: No. of directories: 61

Ques: JWT Signing Algorithms


Ans: HMAC algorithms
This is probably the most common algorithm for signed JWTs.
Hash-Based Message Authentication Codes (HMACs) are a group of algorithms that
provide a way of signing messages by means of a shared key. In the case of HMACs, a
cryptographic hash function is used (for instance SHA256). The strength (i.e. how
hard it is to forge an HMAC) depends on the hashing algorithm being used.

Ques: Default lifetime of JWT token


Ans: Endless till the time server is running

Ques: Joins in mongoDb


Ans: USing Aggregiate

Ques: What is mongoose and its benefits


Ques: what are the various aggregiate function in maongodb

Ques: Types of indexes in mongodb

Ques: Node.js REPL (READ, EVAL, PRINT, LOOP)


Ans:
REPL (READ, EVAL, PRINT, LOOP) is a computer environment similar to Shell
(Unix/Linux) and command prompt. Node comes with the REPL environment when it is
installed. System interacts with the user through outputs of commands/expressions
used. It is useful in writing and debugging the codes. The work of REPL can be
understood from its full form:

Read : It reads the inputs from users and parses it into JavaScript data structure.
It is then stored to memory.
Eval : The parsed JavaScript data structure is evaluated for the results.
Print : The result is printed after the evaluation.
Loop : Loops the input command. To come out of NODE REPL, press ctrl+c twice

Getting Started with REPL:


To start working with REPL environment of NODE; open up the terminal (in case of
UNIX/LINUX) or the Command prompt (in case of Windows) and write node and press
‘enter’ to start the REPL.
The REPL has started and is demarcated by the ‘>’ symbol. Various operations can be
performed on the REPL. Below are some of the examples to get familiar with the REPL
environment.
Example: Performing Arithmetical operations in REPL
ankitb@emer:~/ankit_dev/projects/inst-frontend$ node
Welcome to Node.js v12.19.0.
Type ".help" for more information.
> 10+20
30
> Math.pow(2,2)
4

Ques: Data types in node JS


Ans: Primitive Datatypes of Node.js
There are four core datatypes of node.js
number
boolean
string
object

Special data types of Node.js


There are two special datatypes of node.js
function
array
Buffer

Ques: What is node JS


Ans: Node.js is an open source server-side Javascript run-time environment built on
Chrome’s JavaScript Engine(V8). Node.js is used for building fast and scalable
applications and is an event driven, non-blocking I/O model.

Ques: node js process model


Ans: The Node.js Process Model
The Node.js process model differs from traditional web servers in that Node.js runs
in a single process with requests being processed on a single thread. One advantage
of this is that Node.js requires far fewer resources. When a request comes in, it
will be placed in an event queue. Node.js uses an event loop to listen for events
to be raised for an asynchronous job. The event loop continuously runs, receiving
requests from the event queue.
There are two scenarios that will occur depending on the nature of the request. If
the request is non-blocking, it does not involve any long-running processes or data
requests, the response will be immediately prepared and then sent back to the
client. In the event the request is blocking, requiring I/O operations, the request
will be sent to a worker thread pool. The request will have an associated call-back
function that will fire when the request is finished and the worker thread can send
the request to the event loop to be sent back to the client. In this way, when the
single thread receives a blocking request, it hands it off so that the thread can
process other requests in the meantime. In this way Node.js is inherently
asynchronous.

The combination of the asynchronous nature of Node.js plus the reduced resource
consumption of the single-threaded process leads to a significant increase in
performance. It should be noted, however, that Node.js does not excel with CPU-
intensive operations such as image processing and computationally-expensive work.

Ques: How to create server with node js


Ans: var http = require('http'); // Import Node.js core module

var server = http.createServer(function (req, res) { //create web server


if (req.url == '/') { //check the URL of the current request

// set response header


res.writeHead(200, { 'Content-Type': 'text/html' });

// set response content


res.write('<html><body><p>This is home Page.</p></body></html>');
res.end();

}
else if (req.url == "/student") {

res.writeHead(200, { 'Content-Type': 'text/html' });


res.write('<html><body><p>This is student Page.</p></body></html>');
res.end();

}
else if (req.url == "/admin") {

res.writeHead(200, { 'Content-Type': 'text/html' });


res.write('<html><body><p>This is admin Page.</p></body></html>');
res.end();

}
else
res.end('Invalid Request!');

});

server.listen(5000); //6 - listen for any incoming requests


console.log('Node.js web server at port 5000 is running..');
Ques: Creating server with express
Ans:
const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {


res.send('Hello World!')
})

app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})

Ques: Error-First Callback in Node.js


Ans: Error-First Callback in Node.js is a function which either returns an error
object or any successful data returned by the function.

1) The first argument in the function is reserved for the error object. If any
error has occurred during the execution of the function, it will be returned by the
first argument.
2) The second argument of the callback function is reserved for any successful data
returned by the function. If no error occurred then the error object will be set to
null.
Below is the implementation of Error-First Callback:

Create a file with the name index.js. The file requires an fs module. We will be
implementing an error-first callback function on methods of the fs module. fs
module can be used in the program by using the below command:

const fs = require("fs");
The file can be executed by using the below command:

node index.js
We will be using fs.readFile() to show error-first callback function.
const fs = require("fs");

// This file does not exists


const file = "file.txt";

// Error first callback


// function with two
// arguments err and data
const ErrorFirstCallback = (err, data) => {
if (err) {
return console.log(err);
}
console.log("Function successfully executed");
};

// function execution
// This will return
// error because file do
// not exist
fs.readFile(file, ErrorFirstCallback);

Output:
[Error: ENOENT: no such file or directory, open 'file.txt'] {
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: 'file.txt'
}

Example 2:
const fs = require("fs");

// This file exists


const file = "file.txt";

// Error first callback


// function with two
// arguments err and data
const ErrorFirstCallback = (err, data) => {
if (err) {
return console.log(err);
}
console.log("Function successfully executed");
console.log(data.toString());
};

// function execution
// This will return
// data object
fs.readFile(file, ErrorFirstCallback);
Output:
Function successfully executed
This file exists already

Ques: What is callback hell in node JS


Ans:What is callback hell?
This is a big issue caused by coding with complex nested callbacks. Here, each and
every callback takes an argument that is a result of the previous callbacks. In
this manner, The code structure looks like a pyramid, making it difficult to read
and maintain. Also, if there is an error in one function, then all other functions
get affected.

JavaScript is a strange language. Once in a while, you have to deal with a callback
that’s in another callback that’s in yet another callback.

People affectionately call this pattern the callback hell.

It kinda looks like this:

firstFunction(args, function() {
secondFunction(args, function() {
thirdFunction(args, function() {
// And so on…
});
});
});
How to escape from a callback hell?
JavaScript provides an easy way of escaping from a callback hell. This is done by
event queue and promises.
A promise is a returned object from any asynchronous function, to which callback
methods can be added based on the previous function’s result.
Promises use .then() method to call async callbacks. We can chain as many callbacks
as we want and the order is also strictly maintained.
Promises use .fetch() method to fetch an object from the network. It also
uses .catch() method to catch any exception when any block fails.
So these promises are put in event queue so that they don’t block subsequent JS
code. Also once the results are returned, the event queue finishes its operations.
There are also other helpful keywords and methods like async, wait, settimeout() to
simplify and make better use of callbacks.

Ques: Example of callback hell


Ans:
fs.readdir(source, function (err, files) {
if (err) {
console.log('Error finding files: ' + err)
} else {
files.forEach(function (filename, fileIndex) {
console.log(filename)
gm(source + filename).size(function (err, values) {
if (err) {
console.log('Error identifying file size: ' + err)
} else {
console.log(filename + ' : ' + values)
aspect = (values.width / values.height)
widths.forEach(function (width, widthIndex) {
height = Math.round(width / aspect)
console.log('resizing ' + filename + 'to ' + height + 'x' + height)
this.resize(width, height).write(dest + 'w' + width + '_' + filename,
function(err) {
if (err) console.log('Error writing file: ' + err)
})
}.bind(this))
}
})
})
}
})

Another:
Lets say we want to make entry in multiple tables and we have to do in some order,
so developers make insert call in callback of one table and continue like this.

Ques: What is a stub in Node.js ?


Ans: A small program routine that substitutes for a longer program which is
possible to be loaded later or that is remotely located.
Features of stub:
Stubs can be either anonymous.
Stubs can be wrapped into existing functions. When we wrap a stub into the existing
function the original function is not called.
Stubs are functions or programs that affect the behavior of components or modules.
Stubs are dummy objects for testing.
Stubs implement a pre-programmed response.
Example:
var fs = require('fs')
var writeFileStub = sinon.stub(fs,
'writeFile', function (path, data, cb) {
return cb(null)
})

expect(writeFileStub).to.be.called
writeFileStub.restore()

When to use stubs?

>Prevent a specific method from being called directly.


>Controlling method behavior down a specific path from a test to force the code.
For example: Error handling.
>Replacing the problematic pieces of code.
>Testing asynchronous code easy.
Ex:
mocha.setup('bdd');
function saveUser(user, callback) {
$.post('/users', {
first: user.firstname,
last: user.lastname
}, callback);
}

describe('saveUser', function () {
it('should call callback after saving',
function () {

// We'll stub $.post so a


// request is not sent
var post = sinon.stub($, 'post');
post.yields();

// We can use a spy as the callback


// so it's easy to verify
var callback = sinon.spy();

saveUser({ firstname: 'Han',


lastname: 'Solo' }, callback);

post.restore();
sinon.assert.calledOnce(callback);
});
});

mocha.run();
output:
saveUser
we will call the callback after saving

Ques: Promises in Node.js


Ans:Introduction: Callback functions are used for Asynchronous events.

Example:
module.exports = (x, callback) => {
if (x <= 0)
setTimeout(() =>
callback(new Error("Square dimensions
should be greater than zero: s = " + x),
null), 2000);
else
setTimeout(() =>
callback(null, {
perimeter: () => (4*(x)),
area:() => (x*x)
}), 2000);
}
What are Promises?
A promise is basically an advancement of callbacks in Node. While developing an
application you may encounter that you are using a lot of nested callback
functions.

dboper.insertDocument(db, { name: "Test", description: "Test"},


"test", (result) => {
console.log("Insert Document:\n", result.ops);

dboper.findDocuments(db, "test", (docs) => {


console.log("Found Documents:\n", docs);

dboper.updateDocument(db, { name: "Test" },


{ description: "Updated Test" }, "test",
(result) => {
console.log("Updated Document:\n", result.result);

dboper.findDocuments(db, "test", (docs) => {


console.log("Found Updated Documents:\n", docs);

db.dropCollection("test", (result) => {


console.log("Dropped Collection: ", result);

client.close();
});
});
});
});
});
This is what happens due to the nesting of callback functions. Now imagine if you
need to perform multiple nested operations like this. That would make your code
messy and very complex. In Node.js world, this problem is called “Callback Hell”.
To resolve this issue we need to get rid of the callback functions whilst nesting.
This is where Promises come into the picture. A Promise in Node means an action
which will either be completed or rejected. In case of completion, the promise is
kept and otherwise, the promise is broken. So as the word suggests either the
promise is kept or it is broken. And unlike callbacks, promises can be chained.

Callbacks to Promises
Promises notify whether the request is fulfilled or rejected. Callbacks can be
registered with the .then() to handle fulfillment and rejection. The .then() can be
chained to handle the fulfillment and rejection whereas .catch() can be used for
handling the errors(if any).
Ex: dboper.insertDocument(db,
{ name: "Test", description: "Just a test"},
"test").then((result) => {
console.log("Insert Document:\n", result.ops);
});
Nested Promises: Often you will encounter situations where you need to make use of
nested Promises. Nested promises begin with a .then() and in each of the .then() we
have a return statement. After the return statement, .then() follows in the same
manner.

Example:
MongoClient.connect(url).then((client) => {

const db = client.db(database_name);

database.insertDocument(db, { name: "Test",


description: "Chill Out! Its just a test program!"},
"test")
.then((result) => {
return database.findDocuments(db, "test");
})
.then((documents) => {
console.log("Found Documents:\n", documents);

return database.updateDocument(db, { name: "Test" },


{ description: "Updated Test" }, "test");
})
.then((result) => {
console.log("Updated Documents Found:\n", result.result);

return database.findDocuments(db, "test");


})
.then((docs) => {
console.log("The Updated Documents are:\n", docs);

return db.dropCollection("test");
})
.then((result) => {

return client.close();
})
.catch((err) => alert(err));

})
.catch((err) => alert(err));
Now as compared to using the callbacks, our code looks a lot cleaner than before.
As the .then() can be chained together, therefore every Promise is easy to identify
in the code. The .catch(err) is executed if error(s) occurs.

Creating custom Promises


You can always create your own custom Promises in Node using the new constructor.

var aPromise = new Promise(function(resolve, reject) {


request.get(options, function(err, resp, body) {
if (err) {
reject(err);
} else {
resolve(JSON.parse(body));
}
})
});
Ques:Output
let a = 10;
console.log(a);
function task() {
let a =20;
console.log(a);
if(true) {
let a = 30;
console.log(a);
}
console.log(a);
}
task();
console.log(a);
Ans: 10 20 30 20 10

Ques:Output
var a = 10;
console.log(a);
function task() {
var a =20;
console.log(a);
if(true) {
var a = 30; //since a has function scope, writing var is not making
difference
console.log(a);
}
console.log(a);
}
task();
console.log(a);
Ans: 10 20 30 30 10

Ques: output
console.log(typeof gm);
let gm = function(name) {
console.log('gm')
}
let ge = function(name) {
console.log('ge')
}
Output: Reference error will come
cannot access gm before initializing

Ques: output
gm('arnav');
ge('arnav');

console.log(typeof gm); //output: undefined

var gm = function(name) {
console.log('gm')
}
var ge = function(name) {
console.log('ge')
}
Output: Type error will come
gm is not a function

Ques: output
function printtthis() {
console.log(this);
}
printthis();
Output: Global object get printed because node js runs in global in case of browser
window will get printed.
Object[global]...

Ques:
let obj = {
a: 10,
b: 20,
c: printthis, //here this will point to obj
d: function() {
this.c(); //object
printthis(); //global
console.log(this.c==printthis); //true
}
}
obj.c();
Output:
{a:10, b:20, c: [Function: prinththis]}

let x = obj.c;
x(); //print global object
console.log(x==printthis); //true even with ===, it make diff with primitives only

Ques: let obj1 = {a:10, b:20};


let obj2 = Object.create(obj1);
console.log(obj2); //print {}
obj2.k = 99;
console.log(obj2); //print {k:99}
console.log(obj2.a); // print 10
obj1.a= 44;
console.log(obj2.a); // 44
obj2.a++;
obj1.a = 44;
console.log(obj2.a); // 11

Ques: Making promise


Ans:
const callMe = new Promise((resolve, reject) => {
if(true) {
resolve('resolved');
} else {
reject('false');
}
})
callMe
.then(result=>{
console.log(result)
})
.catch(err => {
console.log(err)
})

convert it to async await

const callMe = async () => {


if(true) {
return "Hello world";
}
}

const parent = async () => {


return await callMe();
}

(async () => {
const a = await callMe();
console.log(a);
})();

output: Hello world

Ques: jwt
Ans: import * as jwt from 'jsonwebtokens';
const encData = jwt.sign({name: mahesh}, process.env.SECRET);
const decData = jwt.verify(encData, process.env.SECRET);
console.log(decData);

Ques: function calculateSalary(job) {


var income=5;
if(job) {
var income = 50;
}
{
var income = 500;
{
var income = 5000;
}
}
return income;
}
console.log(calculateSalary(true));
output: 5000

Ques: this value


1.1 Regular function
Inside of a regular JavaScript function, this value (aka the execution context) is
dynamic.

The dynamic context means that the value of this depends on how the function is
invoked. In JavaScript, there are 4 ways you can invoke a regular function.

During a simple invocation the value of this equals to the global object (or
undefined if the function runs in strict mode):

function myFunction() {
console.log(this);
}
// Simple invocation
myFunction(); // logs global object (window)
During a method invocation the value of this is the object owning the method:

const myObject = {
method() {
console.log(this);
}
};
// Method invocation
myObject.method(); // logs myObject
During an indirect invocation using myFunc.call(thisVal, arg1, ..., argN) or
myFunc.apply(thisVal, [arg1, ..., argN]) the value of this equals to the first
argument:

function myFunction() {
console.log(this);
}
const myContext = { value: 'A' };
myFunction.call(myContext); // logs { value: 'A' }
myFunction.apply(myContext); // logs { value: 'A' }
During a constructor invocation using new keyword this equals to the newly created
instance:

function MyFunction() {
console.log(this);
}
new MyFunction(); // logs an instance of MyFunction
1.2 Arrow function
The behavior of this inside of an arrow function differs considerably from the
regular function's this behavior. The arrow function doesn't define its own
execution context.

No matter how or where being executed, this value inside of an arrow function
always equals this value from the outer function. In other words, the arrow
function resolves this lexically.

In the following example, myMethod() is an outer function of callback() arrow


function:

const myObject = {
myMethod(items) {
console.log(this); // logs myObject
const callback = () => {
console.log(this); // logs myObject
};
items.forEach(callback);
}
};
myObject.myMethod([1, 2, 3]);
this value inside the arrow function callback() equals to this of the outer
function myMethod().

this resolved lexically is one of the great features of arrow functions. When using
callbacks inside methods you are sure the arrow function doesn't define its own
this: no more const self = this or callback.bind(this) workarounds.

Contrary to a regular function, the indirect invocation of an arrow function using


myArrowFunc.call(thisVal) or myArrowFunc.apply(thisVal) doesn't change the value of
this: the context value is always resolved lexically.

Ques: Return third highest and third lowest element in array without using index

Ques: output
for(var j=0;j<5;j++){
setTimeout(()=>console.log(j),10);
}
output:
5
5
5
5
5

Ques: Diff between process.nextTick and setImmediate in node JS.


Ans: process.nextTick is a function that we can use when we really need to execute
a certain callback right after the current event loop phase
Set immediate only runs after the io callback phase

Ques: What is callbackhell


Ans: People affectionately call this pattern the callback hell.

It kinda looks like this:

firstFunction(args, function() {
secondFunction(args, function() {
thirdFunction(args, function() {
// And so on…
});
});
});
This is JavaScript for you. It’s mind-boggling to see nested callbacks, but I don’t
think it’s a “hell”. The “hell” can be manageable if you know what to do with it.

On callbacks
I assume you know what callbacks are if you’re reading this article. If you don’t,
please read this article for an introduction to callbacks before continuing. There,
we talk about what callbacks are and why you use them in JavaScript.

Solutions to callback hell


There are four solutions to callback hell:

Write comments
Split functions into smaller functions
Using Promises
Using Async/await
Before we dive into the solutions, let’s construct a callback hell together. Why?
Because it’s too abstract to see firstFunction, secondFunction, and thirdFunction.
We want to make it concrete.

Constructing a callback hell


Let’s imagine we’re trying to make a burger. To make a burger, we need to go
through the following steps:

Get ingredients (we’re gonna assume it’s a beef burger)


Cook the beef
Get burger buns
Put the cooked beef between the buns
Serve the burger
If these steps are synchronous, you’ll be looking at a function that resembles
this:

const makeBurger = () => {


const beef = getBeef();
const patty = cookBeef(beef);
const buns = getBuns();
const burger = putBeefBetweenBuns(buns, beef);
return burger;
};

const burger = makeBurger();


serve(burger);
However, in our scenario, let’s say we can’t make the burger ourselves. We have to
instruct a helper on the steps to make the burger. After we instruct the helper, we
have to WAIT for the helper to finish before we begin the next step.

If we want to wait for something in JavaScript, we need to use a callback. To make


the burger, we have to get the beef first. We can only cook the beef after we get
the beef.

const makeBurger = () => {


getBeef(function(beef) {
// We can only cook beef after we get it.
});
};
To cook the beef, we need to pass beef into the cookBeef function. Otherwise,
there’s nothing to cook! Then, we have to wait for the beef to get cooked.

Once the beef gets cooked, we get buns.

const makeBurger = () => {


getBeef(function(beef) {
cookBeef(beef, function(cookedBeef) {
getBuns(function(buns) {
// Put patty in bun
});
});
});
};
After we get the buns, we need to put the patty between the buns. This is where a
burger gets formed.

const makeBurger = () => {


getBeef(function(beef) {
cookBeef(beef, function(cookedBeef) {
getBuns(function(buns) {
putBeefBetweenBuns(buns, beef, function(burger) {
// Serve the burger
});
});
});
});
};
Finally, we can serve the burger! But we can’t return burger from makeBurger
because it’s asynchronous. We need to accept a callback to serve the burger.

const makeBurger = nextStep => {


getBeef(function (beef) {
cookBeef(beef, function (cookedBeef) {
getBuns(function (buns) {
putBeefBetweenBuns(buns, beef, function(burger) {
nextStep(burger)
})
})
})
})
}

// Make and serve the burger


makeBurger(function (burger) => {
serve(burger)
})
(I had fun making this callback hell example ?).

First solution to callback hell: Write comments


The makeBurger callback hell is simple to understand. We can read it. It just…
doesn’t look nice.

If you’re reading makeBurger for the first time, you may think “Why the hell do we
need so many callbacks to make a burger? It doesn’t make sense!”.

In such a case, you’d want to leave comments to explain your code.

// Makes a burger
// makeBurger contains four steps:
// 1. Get beef
// 2. Cook the beef
// 3. Get buns for the burger
// 4. Put the cooked beef between the buns
// 5. Serve the burger (from the callback)
// We use callbacks here because each step is asynchronous.
// We have to wait for the helper to complete the one step
// before we can start the next step

const makeBurger = nextStep => {


getBeef(function(beef) {
cookBeef(beef, function(cookedBeef) {
getBuns(function(buns) {
putBeefBetweenBuns(buns, beef, function(burger) {
nextStep(burger);
});
});
});
});
};
Now, instead of thinking “wtf?!” when you see the callback hell, you get an
understanding of why it has to be written this way.

Second solution to callback hell: Split the callbacks into different functions
Our callback hell example is already an example of this. Let me show you the step-
by-step imperative code and you’ll see why.

For getBeef, our first callback, we have to go to the fridge to get the beef. There
are two fridges in the kitchen. We need to go to the right fridge.

const getBeef = nextStep => {


const fridge = leftFright;
const beef = getBeefFromFridge(fridge);
nextStep(beef);
};
To cook beef, we need to put the beef into an oven; turn the oven to 200 degrees,
and wait for twenty minutes.

const cookBeef = (beef, nextStep) => {


const workInProgress = putBeefinOven(beef);
setTimeout(function() {
nextStep(workInProgress);
}, 1000 * 60 * 20);
};
Now imagine if you have to write each of these steps in makeBurger… you’ll probably
faint from the sheer amount of code!

For a concrete example on splitting callbacks into smaller functions, you can read
this small section in my callback article.

Third solution to callback hell: Use promises


I’m going to assume you know what promises are. If you don’t, please read this
article.

Promises can make callback hell much easier to manage. Instead of the nested code
you see above, you’ll have this:

const makeBurger = () => {


return getBeef()
.then(beef => cookBeef(beef))
.then(cookedBeef => getBuns(beef))
.then(bunsAndBeef => putBeefBetweenBuns(bunsAndBeef));
};

// Make and serve burger


makeBurger().then(burger => serve(burger));
If you take advantage of the single-argument style with promises, you can tweak the
above to this:

const makeBurger = () => {


return getBeef()
.then(cookBeef)
.then(getBuns)
.then(putBeefBetweenBuns);
};

// Make and serve burger


makeBurger().then(serve);
Much easier to read and manage.

But the question is how do you convert callback-based code into promise-based code.

Converting callbacks to promises


To convert callbacks into promises, we need to create a new promise for each
callback. We can resolve the promise when the callback is successful. Or we can
reject the promise if the callback fails.

const getBeefPromise = _ => {


const fridge = leftFright;
const beef = getBeefFromFridge(fridge);

return new Promise((resolve, reject) => {


if (beef) {
resolve(beef);
} else {
reject(new Error(“No more beef!”));
}
});
};

const cookBeefPromise = beef => {


const workInProgress = putBeefinOven(beef);

return new Promise((resolve, reject) => {


setTimeout(function() {
resolve(workInProgress);
}, 1000 * 60 * 20);
});
};
In practice, callbacks would probably be written for you already. If you use Node,
each function that contains a callback will have the same syntax:

The callback would be the last argument


The callback will always have two arguments. And these arguments are in the same
order. (Error first, followed by whatever you’re interested in).
// The function that’s defined for you
const functionName = (arg1, arg2, callback) => {
// Do stuff here
callback(err, stuff);
};

// How you use the function


functionName(arg1, arg2, (err, stuff) => {
if (err) {
console.error(err);
}
// Do stuff
});
If your callback has the same syntax, you can use libraries like ES6 Promisify or
Denodeify (de-node-ify) that callback into a promise. If you use Node v8.0 and
above, you can use util.promisify.
All three of them work. You can choose any library to work with. There are slight
nuances between each method, though. I’ll leave you to check their documentation
for how-tos.

Fourth solution to callback hell: Use asynchronous functions


To use asynchronous functions, you need to know two things first:

How to convert callbacks into promises (read above)


How to use asynchronous functions (read this if you need help).
With asynchronous functions, you can write makeBurger as if it’s synchronous again!

const makeBurger = async () => {


const beef = await getBeef();
const cookedBeef = await cookBeef(beef);
const buns = await getBuns();
const burger = await putBeefBetweenBuns(cookedBeef, buns);
return burger;
};

// Make and serve burger


makeBurger().then(serve);
There’s one improvement we can make to the makeBurger here. You can probably get
two helpers to getBuns and getBeef at the same time. This means you can await them
both with Promise.all.

const makeBurger = async () => {


const [beef, buns] = await Promise.all(getBeef, getBuns);
const cookedBeef = await cookBeef(beef);
const burger = await putBeefBetweenBuns(cookedBeef, buns);
return burger;
};

// Make and serve burger


makeBurger().then(serve);
(Note: You can do the same with Promises… but the syntax isn’t as nice and as clear
as async/await functions).

Wrapping up
Callback hell isn’t as hellish as you think. There are four easy ways to manage
callback hell:

Write comments
Split functions into smaller functions
Using Promises
Using Async/await

Ques: what is temporal dead zone

Ques: polyfill for Array.map


Ans:Polyfill is a piece of code (usually written in Javascript) used to provide
modern functionality to older browsers which do not support it natively. It acts as
a browser fallback.

Array.prototype.map()
Javascript supports an inbuilt method map for Array which takes a callback function
& returns an array of the same length after calling the callback function for each
element of the array. Example:
const arr = [1,2,3,4,5];
function double(elem){
return elem*2;
}
const newArr = arr.map(double);
console.log(newArr);
// [2,4,6,8,10]

Polyfill for Array.prototype.map()


First of all let understand what are the expected arguments to be passed to this
method. From the MDN docs we can see that map method can take 2 arguments.

1. callbackFn: This function will be called for every element of the array and
returns a value which will be added to the new array. This function can again take
3 arguments.
a. element: The current element being processed in the array.
b. index (Optional): The index of the current element being processed in the array.
c. array (Optional): The array on which map was called.
2. thisArg (Optional)
Now this how I would my implementation for a basic version of Array.prototype.map()
look like:

Array.prototype.myMap = function(callbackFn){
const arr = this;
const resultArr = [];
for(let i=0; i<arr.length; i++){
const newElem = callbackFn(arr[i]);
resultArr.push(newElem);
}
return resultArr;
}
function double(elem, index, arr){
return elem*2;
}
const newArr = arr.myMap(double);
console.log(newArr);
// [2,4,6,8,10]

We can obviously add more error handling scenarios to make this method more robust
and practically useful, but from an interview's point this might be sufficient
usually.

Ques: polyfill for Function.bind


Ans: Function.prototype.bind()
Javascript provides an inbuilt method to be used with functions called bind which
takes a this value as it's argument and returns the function with the provided this
value.
For Example:
const shivObj = {
name: "Shivaansh Agarwal",
work: "Frontend Developer"
};
function printUserInfo(city){
console.log(`Hey I'm ${this.name} working as a ${this.work} from ${city}.`);
}
const getMyDetails = printUserInfo.bind(shivObj, "Bangalore");
getMyDetails();
// Hey I'm Shivaansh Agarwal working as a Frontend Developer from Bangalore.

Polyfill for Function.prototype.bind()


Firstly, let's understand what the actual bind method takes as an input. So from
MDN documentation for bind method we came to know that, bind method takes the
following arguments as input.

1. thisArg: The value to be passed as the this parameter to the target function
when the bound function is called.
2. arg1, arg2, ... argN (Optional): The arguments to be passed to the actual
function.
Secondly, what is the bind supposed to return? It's supposed to return a copy of
the given function, with the specified this value, and the arguments (if passed).

Now this how I would my implement a basic version of Function.prototype.bind()


Let's name this myBind()
Function.prototype.myBind = function(thisArg, ...args){
const functionRef = this;
return function(...params){
functionRef.apply(thisArg, [...args, ...params])
}
}
const shivObj = {
name: "Shivaansh Agarwal",
work: "Frontend Developer"
};
function printUserInfo(city){
console.log(`Hey I'm ${this.name} working as a ${this.work} from ${city}.`);
}
const getMyDetails = printUserInfo.myBind(shivObj, "Bangalore");
getMyDetails();
// Hey I'm Shivaansh Agarwal working as a Frontend Developer from Bangalore.

Ques: We've the following function greet, we need to find out how many times this
function has been called.
function greet(){
console.log("Hello World!");
}
Ans:
Approach-1
Using a global variable to maintain a count of the number of times this function
can be called.
let count = 0;
function greet(){
count++;
console.log("Hello World");
}
greet();
greet();
greet();
console.log(count); // 3
Problem: This approach works fine, but there's an issue that, any other part in the
codebase can manipulate the count variable.

Approach-2
Using Function Closure
function getGreetings(){
let _count = 0;
function greet(){
_count++;
console.log("Hello, my name is Shivaansh");
}
function getGreetCount(){
console.log(_count);
}
return {
greet,
getGreetCount
}
}

let {greet, getGreetCount} = getGreetings();


getGreetCount();
greet();
greet();
greet();
getGreetCount();
greet();
greet();
getGreetCount();
O/Pimage.png

Approach-3
Using IIFE
const {greet, getCount} = (function(){
let count = 0;
function getCount(){
return getCount;
}
function greet(){
count++;
console.log("Hello World");
}
return {
greet,
getCount
};
})();
greet();
greet();
greet();
console.log(getCount); // 3
With this approach, we can ensure that no other piece of code can change the count
variable. Here the greet function will have a closure with the count variable so
with the use of concepts like IIFE and Closures, we would be able to achieve the
requirement

Ques: Polyfill for Array.filter


Ans:
JavaScript array has an inbuilt method filter() which takes a callback function as
input and returns a new array with the all elements the has passed the test
implemented in the callback function.

Example
const arr = [1, 2, 3, 4, 5, 6];
const filtered = arr.filter((e) => e % 2 === 0);
console.log(filtered);

//[2, 4, 6]
I have checked what arguments this callback takes and found that this callback
function takes three arguments, element, index of the element, and the original
array itself.

Polyfill array filter


Array.filter polyfill
It is extremely common question in JavaScript interviews where it is asked to
implement polyfill for the filter() method.

A polyfill is a browser fallback, made in JavaScript, that allows functionality you


expect to work in modern browsers to work in older browsers.

Array.filter polyfill should have these three functionalities.

The filter() function should take an callback function as an argument.


Current element, its index, and the context should be passed as an argument to the
callback function.
All the elements which pass text implemented in this callback function should be
returned in a new array.

Array.prototype.filter = function (callback) {


//Store the new array
const result = [];
for (let i = 0; i < this.length; i++) {
//call the callback with the current element, index, and context.
//if it passes the text then add the element in the new array.
if (callback(this[i], i, this)) {
result.push(this[i]);
}
}

//return the array


return result
}

Ques: Convert entity relation array to object in Javascript

Given an array with two entries, parent and child relation, convert the array to
relation tree object (parent -> child -> grandchild) in JavaScript.

The input array will contain relation for many ancestry in random order, We must
return the array of object tree from where the tree starts.

For example, in the below case the top most ancestor is animal.

Example
Input:
[
["lion", "cat"],
["cat", "mammal"],
["dog", "mammal"],
["mammal", "animal"],
["fish", "animal"],
["shark", "fish"],
];

Output:
//animal -> mammal -> cat -> lion
//animal -> mammal -> dog
//animal -> fish -> shark

[{
value: "animal",
type: "parent",
children: [
{
value: 'fish',
type: "child",
children: [
{
value: 'shark',
type: "child",
children: []
}
]
},
{
value: 'mammal',
type: "child",
children: [
{
value: 'cat',
type: "child",
children: [
{
value: 'lion',
type: "child",
children: []
}
]
},
{
value: 'dog',
type: "child",
children: []
}
]
}
]
}]
Ans: Convert relation array to object tree in JavaScript.
As the input is in random order, I have decided not to go with recursive solution,
because moving up and down the hierarchy will add lots of complexity.

Rather than that what I did is I used one extra variable to store the entities
reference. Now no matter at what level the entries lies, we don’t have to always
traverse to that level, all we have to do is update the value in reference and it
will be reflected in the output, because the object is passed by reference.
This way we can implement the solution in linear time and using linear space.

Conceptually this is how it works,

Traverse the array in any order.


As we now the relations is stored in backward order for each array entry, that is
arr[index][1] (parent) -> arr[index][0] (child), so we create two different
entities for both the values.
If parent exits then we push the child entity as its children.
Else if the parent does not exits then we add the child to the parent and then
create new entry for parent.
Each entity holds the value (name), children’s array (children), and type whether
it is parent or child.
By default each entry is parent, but if we pass the entry as child then we update
its type to child, thus we are left with only parent who is the start of ancestry.
At the end filter only parent type entities and return it.
//helper function to create entity
const structure = (value, type) => ({ value, children: [], type });

//func to create relation


const relations = (inp) => {
//tracks each entry separately
let exits = {};

//iterate the array in reverse order


for (let i = inp.length - 1; i >= 0; i--) {
//get the first and last entry of each inp
const [a, b] = inp[i];

//if there is no entry for parent


if (!exits[b]) {
//create parent
const parent = structure(b, "parent");

//if child already exits use it


//else create new child
const child = exits[a] ? exits[a] : structure(a, "Child");

//if it was parent previously


//convert it to child before adding
child.type = "child";

//push child to parent


parent.children.push(child);

//mark the entry of parent and child


exits[b] = parent;
exits[a] = child;
}
// if parent already exits
else {
//if child already exits use it,
//else create new child
const child = exits[a] ? exits[a] : structure(a, "child");

//if it was parent previously


//convert it to child before adding
child.type = "child";
//add the child to the parent
exits[b].children.push(child);

//if child does not exits mark its entry


if (!exits[a]) {
exits[a] = child;
}
}
}

//return array of parent elemnts where ancestory starts


return Object.keys(exits).reduce((a, b) => {
if (exits[b].type === "parent") {
a.push(exits[b]);
}

return a;
}, []);
};
const entities = [
["lion", "cat"],
["cat", "mammal"],
["dog", "mammal"],
["fish", "animal"],
["shark", "fish"],
["mammal", "animal"],
["flying", "bird"],
["non-flying", "bird"],
["ostrich", "non-flying"],
["eagle", "flying"],
];

console.log(relations(entities));

Output:
[
{
value: "bird",
type: "parent",
children: [
{
value: 'non-flying',
type: "child",
children: [
{
value: 'ostrich',
type: "child",
children: []
}
]
},
{
value: 'flying',
type: "child",
children: [
{
value: 'eagle',
type: "child",
children: []
}
]
}
]
},
{
value: "animal",
type: "parent",
children: [
{
value: 'fish',
type: "child",
children: [
{
value: 'shark',
type: "child",
children: []
}
]
},
{
value: 'mammal',
type: "child",
children: [
{
value: 'cat',
type: "child",
children: [
{
value: 'lion',
type: "child",
children: []
}
]
},
{
value: 'dog',
type: "child",
children: []
}
]
}
]
}
]

Ques: Filter nested object in Javascript


Ans: Create a function in javascript which will take a nested object and a filter
function as input and return the filtered object.

Example
Input:
const obj = {
a: 1,
b: {
c: "Hello World",
d: 2,
e: {
f: {
g: -4,
},
},
h: "Good Night Moon",
},
};

const filter = (s) => typeof s === "string";

Output:
{
b: {
c: "Hello World",
h: "Good Night Moon",
}
};
The only clause to this function is that filtering should happen in-place, which
means we cannot create a copy of this object and then perform operation on it.

We can filter the object by removing the entries in object which fails the filter
condition. Basically we have to handle the following cases.

Iterate all the entries of the object and in each iteration check.
If the value of the current key is an object then recur and call the same function
with the current value.
Else, if the value is empty object or fails the filter condition then delete the
current object.
To check if the value is empty object or not, we will convert the value to string
using JSON.stringify() method and then compare it.

const deepFilter = (obj, filter) => {


//iterate the object
for (let key in obj) {
const val = obj[key];

//if val is also object (nested)


if (typeof val === "object") {
//recur
deepFilter(val, filter);
}
// normal value
else {
//current val fails filter condition
//delete it
if (filter(val) === false) {
delete obj[key];
}
}

//if value is empty obj


//delete it
if (JSON.stringify(val) === "{}") {
delete obj[key];
}
}
};
Input:
const obj = {
a: 1,
b: {
c: "Hello World",
d: 2,
e: {
f: {
g: -4,
},
},
h: "Good Night Moon",
},
};

//filter's in-place
deepFilter(obj, (s) => typeof s === "string");

console.log(obj);

Output:
{
b: {
c: "Hello World",
h: "Good Night Moon",
}
};

Ques: Deep flatten object in Javascript – 1


Ans: Given an nested object which can have any type of object, deep flatten it and
return the new object in Javascript.

For example
Input:
{
A: "12",
B: 23,
C: {
P: 23,
O: {
L: 56
},
Q: [1, 2]
}
}

Output:
{
"A": "12"
"B": 23,
"C.O.L": 56,
"C.P": 23,
"C.Q.0": 1,
"C.Q.1": 2,
}
Deep flatten object Javascript
In the output if you notice, when we have nested objects the key is concatenated
till there is a non-object value, similar for the array, the key is concatenated on
the index.

Given the way we want the output, there are two ways in which we can solve this
problem, one is using stack and other is using recursion.

In this case we will go with recursion as I find it simpler to handle recursive


functions.

There are three different cases which we need to handle.

Check if the value of the given key is object or not.


If it is not an object then add that value to the output.
Else, check if the value is array or not.
If it is object then recursively call the same function with value and pass the key
to be used as prefix and return the output in existing result.
Otherwise, iterate the value and use the array’s index along with existing key as a
new key and then store it in the output.
Alternatively, we can convert the array to object and then recursively call the
same function as we did in step 4.
We are going to see the both approaches along with two different ways to check the
type of value.

Approach 1.
const flatten = (obj, prefix) => {
//store the result
let output = {};

//iterate the object


for(let k in obj){
let val = obj[k];

//get the type


const type = Object.prototype.toString.call(val);

//object
if(type === "[object Object]"){
//new key
const newKey = prefix ? prefix + "." + k : k;
const newObj = flatten(val, newKey);
output = {...output, ...newObj};

}
//array
else if(type === "[object Array]"){
//iterate array
for(let i = 0; i < val.length; i++){
//new key
const newKey = prefix ? prefix + "." + k + "." + i : k + "." + i;
output = {...output, [newKey]: val[i]};
}
}
// normal value
else{
//new key
const newKey = prefix ? prefix + "." + k : k;
output = {...output, [newKey]: val};
}
}
return output;
}
Input:
const nested = {
A: "12",
B: 23,
C: {
P: 23,
O: {
L: 56
},
Q: [1, 2]
}
};

console.log(flatten(nested));

Output:
{
"A": "12"
"B": 23,
"C.O.L": 56,
"C.P": 23,
"C.Q.0": 1,
"C.Q.1": 2,
}
Approach 2.
The problem in the first approach is we have to create the new key in each
condition which is not a good and it is because we are iterating the array in
between, if we could convert that array to object then we can get rid of this
problem.

Also we can use ES6 features to differentiate between object and array.

const flatten = (obj, prefix) => {


//store the result
let output = {};

//iterate the object


for(let k in obj){
let val = obj[k];

//new key
const newKey = prefix ? prefix + "." + k : k;

//array and object both are object in js


if(typeof val === "object"){
// if it is array
if(Array.isArray(val)){
//use rest & spread together to convert
//array to object
const { ...arrToObj } = val;
const newObj = flatten(arrToObj, newKey);
output = {...output, ...newObj};
}
//if it is object
else{
const newObj = flatten(val, newKey);
output = {...output, ...newObj};
}
}
// normal value
else{
output = {...output, [newKey]: val};
}
}

return output;
}
Input:
const nested = {
A: "12",
B: 23,
C: {
P: 23,
O: {
L: 56
},
Q: [1, 2]
}
};

console.log(flatten(nested));

Output:
{
"A": "12"
"B": 23,
"C.O.L": 56,
"C.P": 23,
"C.Q.0": 1,
"C.Q.1": 2,
}

Ques: How to flat an array in javascript


Ans:
Learn how to flat an array in javascript.

Flattening an array is simple process of merging different N dimensional sub arrays


to form a single array.

For example

Input:
[[[1, [1.1]], 2, 3], [4, 5]]

Output:
[1, 1.1, 2, 3, 4, 5]
ES2019 has introduced two new array methods flat and flatMap which can be used to
flatten an array.

But as these methods are added recently they are supported only by newer versions
of browsers. Firefox 62+, Chrome 69+, Edge 76+ and Safari 12+ currently have the
support.

You can check the current browser support for it before using it.
On the other hand if you are using babel then it will backport your code to
previous version.

Flat an array in javascript


flat is the new array method which merges the multi dimensional sub arrays to
create an one dimensional array with all the elements of sub array.

[1, 2, [3, 4]].flat();


//[1, 2, 3, 4]
By default it only supports flattening for one level. But luckily it accepts an
extra parameter which can be used to decide the level.

[1, 2, [3, 4]].flat(1);


//[1, 2, 3, 4]

[1, 2, [3, 4], [[5]]].flat(2);


//[1, 2, 3, 4, 5]
Pass Infinity to flat till any level.

[[[1, [1.1]], 2, 3], [4, 5]].flat(Infinity);


//[1, 1.1, 2, 3, 4, 5]
flatMap is combination of flat and map method of array. It keeps flattening all the
array elements.

//map
['Prashant Yadav', 'Learners Bucket'].map(e => e.split(' '));
//[['Prashant', 'Yadav'], ['Learners', 'Bucket']];

//flatMap
['Prashant Yadav', 'Learners Bucket'].flatMap(e => e.split(' '));
//['Prashant', 'Yadav', 'Learners', 'Bucket'];
Polyfill
In case you don’t want to use any extra library for a single method. You can create
you our own custom function for array flattening.

This is the first method which uses modern ES6 features.

const flatten = (arr) => {


return arr.reduce((flat, toFlatten) => {
return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
}, []);
}
Second method which uses normal array functions.

const flatten = function(arr, result = []) {


for (let i = 0, length = arr.length; i < length; i++) {
const value = arr[i];
if (Array.isArray(value)) {
flatten(value, result);
} else {
result.push(value);
}
}
return result;
};

Ques: Restrict modification of object properties in javascript.


Ans:
Learn how to restrict adding, removing and changing or simply the modification of
object properties in javascript.

Objects are the backbone of the javascript programming language as most of its
features are actually object, like arrays, functions, etc.

So to make objects so powerful it was obvious that it should be able to modify or


extend so that we can use it in different forms.

But there are scenarios where we want to restrict this modification to some limit
or completely.

Here we will see two different objects methods that can you used to achieve the
same.

Using Object.seal() to restrict object change.


First, we will see a scenario where we want to restrict an object to become
extendible.

For example, we should be able to modify the existing properties or methods of the
objects but cannot add a new one. Object.seal() can be used to achieve the same but
it also marks all existing properties as non-configurable like we cannot delete
them but just update their value if it is writable.

const obj = {
prop: 42
};

Object.seal(obj);
obj.prop = 33;
console.log(obj.prop);
// 33

delete obj.prop; // cannot delete when sealed


console.log(obj.prop);
// 33
But we cannot restrict the modification of nested objects with Object.seal().

const obj = {
prop: 42,
nested: {
a: 1,
b: 2
}
};

//Seal the object


Object.seal(obj);

obj.nested.a = 2;
delete obj.nested.a;
console.log(obj.nested.a);
// undefined
However, we can create another helper function which will deep seal or seal the
nested objects as well.

function deepSeal(object) {
// Retrieve the property names defined on object
let propNames = Object.getOwnPropertyNames(object);

// Seal properties before Sealing self


for (let name of propNames) {
let value = object[name];

object[name] = value && typeof value === "object" ?


deepSeal(value) : value;
}

return Object.seal(object);
}
Now this will seal the nested objects as well.

const obj = {
prop: 42,
nested: {
a: 1,
b: 2
}
};

//Seal the object


deepSeal(obj);

obj.nested.a = 2;
delete obj.nested.a;
console.log(obj.nested.a);
// 2
You can use Object.isSealed() to check if an object is sealed or not.

const obj = {
prop: 42,
nested: {
a: 1,
b: 2
}
};

//Seal the object


deepSeal(obj);

console.log(Object.isSealed(obj));
//true
Using Object.freeze() to restrict modification of object properties.
Unlike Object.seal(), Object.freeze() freezes the object completely. It does not
even allow changing of object properties.

const obj = {
prop: 42
};

Object.freeze(obj);

obj.prop = 33;
// Throws an error in strict mode

console.log(obj.prop);
// 42
But this also only shallow freezes the object properties.

const obj = {
prop: 42,
nested: {
a: 1,
b: 2
}
};

Object.freeze(obj);

obj.nested.a = 33;
// Updates the value

console.log(obj.nested.a);
// 33
Like deepSeal() we can also create a deepFreeze() function that will freeze the
nested objects as well.

function deepFreeze(object) {
// Retrieve the property names defined on object
var propNames = Object.getOwnPropertyNames(object);

// Freeze properties before freezing self


for (let name of propNames) {
let value = object[name];

object[name] = value && typeof value === "object" ?


deepFreeze(value) : value;
}

return Object.freeze(object);
}
const obj = {
prop: 42,
nested: {
a: 1,
b: 2
}
};

deepFreeze(obj);

obj.nested.a = 33;
// Updates the value

console.log(obj.nested.a);
// 1
You can use Object.isFrozen() to check if an object is frozen or not.

const obj = {
prop: 42,
nested: {
a: 1,
b: 2
}
};
//Seal the object
deepFreeze(obj);

console.log(Object.isFrozen(obj));
//true

Ques: How to do lazy loading in javascript

Learn how to do lazy loading in javascript to fetch any type of content.

Let us learn this buy building a lazy image loading feature.

What is lazy image loading?


Many websites like Facebook, Linkedin, Pinterest or ecommerce sites like Flipkart,
Amazon have lots of image, They do no load all image at once on page load.

Instead what they do is load images as we scroll down or the image is in the
viewport of the screen.

To achieve this functionality we will need to do three things.

1. We will store the image source in a custom HTML attribute so that we can use it
to load the image.

<img data-src="https://cdn.pixabay.com/photo/2018/09/16/15/31/boy-3681679_1280.jpg"
/>
and may be use a class to access all the images at once.

<img class="lazy-image"
data-src="https://cdn.pixabay.com/photo/2018/09/16/15/31/boy-3681679_1280.jpg" />
2. Check if the image is in the view port or visible in the screen. To do this we
will calculate the difference between the image and the screen with a buffer.

We are using buffer so that image could be loaded even if it is half visible only.

//Buffer
let inAdvance = 100;

//This will check if the image is inside the viewport or not.


if(image.offsetTop < window.innerHeight + window.pageYOffset + inAdvance)
3. Now we have to create a function which will be doing the lazy loading and call
this when window is scrolled or resized.

//Prefetch all the images


//Repeating this inside function will hamper the performance
let lazyImages = [...document.querySelectorAll('.lazy-image')];

//Buffer
let inAdvance = 50;

const lazyLoad = () => {


//Iterate all the images and check
lazyImages.forEach(image => {
if (image.offsetTop < window.innerHeight + window.pageYOffset + inAdvance)
{
//if image is in viewport set the src from custom attribute
//dataset is used to get the custom attribute
image.src = image.dataset.src;

//if the image is loaded then add class to it


image.onload = () => image.classList.add('loaded')
}
});
};

//Call the function to load the first image


lazyLoad();

//lazy load the function when window is scrolled


window.addEventListener('scroll', throttle(lazyLoad, 700));

//lazy load the function when window is resized


window.addEventListener('resize', throttle(lazyLoad, 700));
We are using throttle to limit the number of time a function can be called. It will
be called again after the specified time only.

Ques: What is throttling in javascript?

Learn what is throttling in javascript.

Excessive function invocations in javascript applications hamper the performance


drastically. To optimize an app we need to handle this correctly.

There are scenarios where we may invoke functions when it isn’t necessary. For
example, consider a scenario where we want to make an API call to the server on a
button click.

If the user spam’s the click then this will make API call on each click. This is
not what we want, we want to restrict the no of API calls that can be made. The
other call will be made only after a specified interval of time.

Debouncing and Throttling help us to gain control over the rate at which function
is called or executes.

What exactly is throttling in javascript?


Throttling is a way/technique to restrict the number of function execution/call.
For example, consider a lucky draw number generator, we want to get a number only
after a particular time.

With throttling, we can achieve this.

Here is the code for throttling in javascript.

const throttle = (func, limit) => {


let lastFunc;
let lastRan;
return function() {
const context = this;
const args = arguments;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function() {
if ((Date.now() - lastRan) >= limit) {
func.apply(context, args)
lastRan = Date.now()
}
}, limit - (Date.now() - lastRan));
}
}
}
This will call/execute the specified function only after a given interval no matter
how much you call it.

btn.addEventListener('click', throttle(function() {
return console.log('HOLA! oppo', new Date().toUTCString());
}, 1000));
Then what is the difference between debouncing and throttling?
Debouncing:- It is used to invoke/call/execute function only when things have
stopped happening for a given specific time. For example, Call a search function to
fetch the result when the user has stopped typing in the search box. If the user
keeps on typing then reset the function.

Throttling:- It is used to restrict the no of time a function can be


called/invoked/executes. For example, making an API call to the server on the
user’s click. If the user spam’s the click then also there will be specific calls
only. Like, make each call after 10 seconds.

Ques: What is debouncing in javascript?

Learn what is debouncing in javascript.

Optimizing performance often crops up in javascript application. Well, there many


things that need to be considered while optimizing an app.

Excessively invoking the function majorly hampers the performance in javascript and
considered as one of the key hurdles.

There are scenarios where we may invoke functions when it isn’t necessary. For
example, consider a callback function that we want to execute on the window resize.
It does not make any sense to call the function as we keep resizing.

We need to execute the callback function only when the resizing is finished.

Debouncing and Throttling help us to gain control over the rate at which function
is called or executes.

What exactly is debouncing in javascript?


Debouncing is a method or a way to execute a function when it is made sure that no
further repeated event will be triggered in a given frame of time.

A technical example is when we search something on any eCommerce site, we don’t


want to trigger search function and make a request to the server as the user keeps
typing each letter. We want the user to finish typing and then wait for a specified
window of time to see if the user is not going to type anything else or has
finished typing and return the result.

Here is the code to implement the debounce function in javascript.


const debounce = (func, delay) => {
let inDebounce;
return function() {
const context = this;
const args = arguments;
clearTimeout(inDebounce);
inDebounce = setTimeout(() => func.apply(context, args), delay);
};
};
We the code is self-explanatory but let me explain it as well.

We created a function that will return a function. The outer function uses a
variable to keep track of time for the execution of the inner function.

The inner function will be called only after a specified window of time, to achieve
this we use setTimeout function inDebounce = setTimeout(() => func.apply(context,
args), delay);.

We store the reference of delayed function so that we can clear it if the outer
function is re-invoked before the specified time clearTimeout(inDebounce) and again
recall it.

If we are invoking for the first time, our function will execute at the end of our
delay. If we invoke and then reinvoke again before the end of our delay, the delay
restarts.

Here is how we can use debounce in javascript.

btn.addEventListener('click', debounce(function() {
console.info('HOLA! oppo', new Date().toUTCString());
}, 3000));

Ques: Compare two array or object with JavaScript


Ans:
Basic approach to compare array and object in javascript.
The most basic approach is to convert the whole array or the object to a string
then compare if those strings are equal or not.

To convert an array or object we will be using JSON.stringify().

let a = [1, 2, 3, 4, 5];


let b = [1, 2, 3, 4, 5];

// "[1, 2, 3, 4, 5]"==="[1, 2, 3, 4, 5]"


console.log(JSON.stringify(a) === JSON.stringify(b));

//true
This may seem to be working fine, but this approach fails when we change the order
of the elements.

let a = [1, 2, 3, 4, 5];


let b = [1, 2, 4, 5, 3];

// "[1, 2, 3, 4, 5]"==="[1, 2, 4, 5, 3]"


console.log(JSON.stringify(a) === JSON.stringify(b));
//false
Technically both the arrays are having the same elements and are equal in length
but it fails in the comparison. The same happens with the objects.

let a = {a: 1, b: 2, c: 3};


let b = {b: 2, a: 1, c: 3};

//"{'a':1,'b':2,'c':3}" "{'b':2,'a':1,'c':3}"
console.log(JSON.stringify(a) === JSON.stringify(b));

//false
Comparing only arrays (Single and Multi dimensional).
We will create our own custom function which will compare only two different
arrays.

In this, we will check

If both the inputs are array or not.


If the current element is array (muti-dimensional) then recursively check its
elements with the corresponding element.
Else compare both the elements and return the result.
let compare = (arr1,arr2) => {
//If not array then return false
if(!arr1 || !arr2) return false;

if(arr1.length !== arr2.length) return false;

let result;

arr1.forEach(e1 => arr2.forEach( e2 => {


if(e1.length > 1 && e2.length){
//If nested array then recursively compare it
result = compare(e1, e2);
}else if(e1 !== e2 ){
result = false
}else{
result = true
}
})
);

return result
}

console.log(compare([1,2,3],[1,2,3]));
// true

console.log(compare([1,2],[1,2,3]));
//false

console.log(compare([[1, 2], [3, 4]],[[1, 2],[3, 4, 6]]));


//false

console.log(compare([[1, 2], [3, 4]],[[1, 2], [3, 4]]));


//true

console.log(compare([1, 2, [3, 4, 5]],[1, 2, [3, 4, 5]]));


//true
console.log(compare([], [1, 2, [3, 4, 5]]));
//false
This method works great if you only have arrays and nested arrays. If it will
contain an object or function then it will fail.

Method 3:- Compare array or object with javascript.


This is a much more robust way to check if two different arrays or objects are
equal or not.

With this method, we will be comparing more complex arrays.


let compare = (current, other) => {
// Get the inputs type
let currentType = Object.prototype.toString.call(current);

// Get the other type


let otherType = Object.prototype.toString.call(other);

// If items are not an object or array, return false


if (['[object Array]', '[object Object]'].indexOf(currentType) < 0 || ['[object
Array]', '[object Object]'].indexOf(otherType) < 0) return false;

// If the two inputs are not the same type, return false
if (currentType !== otherType) return false;

// Compare the length of the length of the two items


let currentLen = currentType === '[object Array]' ? current.length :
Object.keys(current).length;
let otherLen = otherType === '[object Array]' ? other.length :
Object.keys(other).length;
if (currentLen !== otherLen) return false;

//Helper function to check the equality


let equal = (item1, item2) => {
// Get the object type
let itemType = Object.prototype.toString.call(item1);

// If an object or array, compare recursively


if (['[object Array]', '[object Object]'].indexOf(itemType) >= 0) {
if (!compare(item1, item2)) return false;
}else{
// If the two items are not the same type, return false
if (itemType !== Object.prototype.toString.call(item2)) return false;

// If it's a function, convert to a string and compare


// Otherwise, just compare
if (itemType === '[object Function]') {
if (item1.toString() !== item2.toString()) return false;
} else {
if (item1 !== item2) return false;
}
}
};

// Compare properties
if (currentType === '[object Array]') {
for (var i = 0; i < currentLen; i++) {
// Compare the item
if (equal(current[i], other[i]) === false) return false;
}
} else {
for (var key in current) {
if (current.hasOwnProperty(key)) {
// Compare the item
if (equal(current[key], other[key]) === false) return false;
}
}
}

//If all tests are passed then


return true
}

Ques:Pollyfill for Array.reduce()


Let’s first see how Array.reduce() works from its syntax:
arr.reduce(callback( accumulator, currentValue, [, index[, array]] )[,
initialValue])
So, the original Array.reduce function takes two arguement :
1. A callback function as an argument and that callback function can have four
arguments passed into it :
a. accumulator
b. current value
c. index of the current value [optional]
d. array [optional]
2. An initial value.
Based on that, let’s build our own reduce function :
Array.prototype.myReduce= function(callbackFn, initialValue) {
var accumulator = initialValue;
for (var i = 0; i < this.length; i++) {
if (accumulator !== undefined) {
accumulator = callbackFn.call(undefined, accumulator, this[i], i, this);
} else {
accumulator = this[i];
}
}
return accumulator;
}

Ques: Implement your own map, reduce, filter or any new array method in Javascript
| Prototypes
Javascript has many inbuilt methods for Javascript Array. In this blog, we will
implement our own map, reduce, filter methods. We will also learn to write any
custom method for Javascript Arrays.

Implement your own map, reduce, filter or any new array method in Javascript |
Prototypes
All the inbuilt methods are part of Array Prototype and they can can access the
array that’s calling the function by referring to the current scope. You can read
about prototypes and prototype chain if you aren’t aware of it.
Let’s implement a custom function sum:
var arr = [1,2,3];
arr.sum()
Output: 6
In order to implement this we should understand that this doesn’t work as normal
function. We have to add sum method to Array Prototype.
Array.prototype.sum = function(){
var sum = 0;
for(var i=0;i<this.length;i++){
sum =+ this[i];
}
return sum
}

Adding a sum method to Array.prototype gives us access to the current scope, which
is nothing but arr.

We can access arr by using “this” as this refers to the current scope on which this
method is called.
What we can see here is that we are trying to implement the logic for sum inside
the sum method. But in order to create map, reduce, filter, we need to implement a
method that can take the modifier from outside in order to make it more generic.

Array.prototype.map = function(callback){
var mapArray = [];
for(var i=0;i<this.length;i++){
mapArray.push(callback(this[i]))
}
return mapArray
}

arr.map((n) => {
return n+1;
})

Output: [2,3,4]

Here we can see that we are taking the modifier from outside in form of callback.
Callback is responsible for modifying the data of the original array. We are giving
user the flexibility to write its own map.

Similarly with Filter,


Array.prototype.filter = function(callback){
var filterArray = [];
for(var i=0;i<this.length;i++)
if(callback(this[i])){
filterArray.push(this[i])
}
}
return filterArray
}

arr.filter((n) => {
return n == 1;
})

Output: [1]

And Reduce,
Array.prototype.reduce = function(callback, accumulator){
for(var i=0;i<this.length;i++){
accumulator =+callback(accumulator,this[i])
}
return accumulator
}
arr.reduce((n,m) => {
return n+m;
}, 0)

Output: 6

Ques: How to Memoize any Function in Javascript | Memoization


Memoization is widely used programming technique which speeds up the execution of
complex functions by caching the previously calculated results and returning the
result directly from the cache when same input occurs. It is a commonly applied
optimization technique across different frameworks as well.
For example you can consider a factorial function or any complex mathematical
function. We can store its result in Cache which is a temporary storage. We will
use a object here.
In order to implement memoization, you should be aware of closures and higher order
functions which we used in ADD(1)(2)(3)…(N)() IN JAVASCRIPT | SUM(1,2)(3,4) |
CURRYING example. You can refer to this post to understand how currying works and
how we use higher order functions.
Closure gives the access to outer functions scope from inner function. It can
access even after the outer function has returned. If you wan’t me to cover this in
details then post a comment or you can refer to many tutorials across the web. This
is a very hot Javascript Interview Question as well.
With this knowledge, let’s jump into our code. For example, we will consider a
simple multiplication function. Although, memoization is advisable to only complex
operations.
Let’s write a function memoized that will return the memoized function of multiply
or any other function.

var multiply = function(a,b) {


return a*b;
}

var memoized = function(foo) {


var cache = {};
return function(...args) {
var argId = arg.toString();
if(cache[argId]) {
return cache[argId];
} else {
var value = foo(...args);
cache[argId] = value;
return value;
}
}
}
et’s break it down,

Function memoized takes another function foo


cache is just an empty Javascipt Object
We are returning another function that will serve as memoized function
args is a parameter that handles the arguments of original function
Rest operator(…) allows us to accept infinite parameters i.e a , b in multiply
function
We create a unique id combining all parameters
We check if that key has a value in cache object. If yes we return the value
Else we call original function with all arguments
Store the returned value in Cache and return the value.
Since we have created a closure, we can access cache object even after function has
returned. Let’s do the magic,

Conclusion: I hope you liked my post on How to Memoize any Function in Javascript |
Memoization. This is how we can optimize any performance heavy function. Please
comment if you want to share your solution. Memoization is also an important
Javascript Interview Question which you should be aware of.

Ques: How to Scale Website | CDN | Load Balancers | Walmart Interview


In order to Scale Website, you need to ensure that your website remains accessible
even if website traffic grows exponentially i.e website/application should be able
to handle more and more concurrent requests. I was asked this question in my
Walmart Interview for Frontend Engineer position.
Let’s see what are the ways to scale website:

CDN – Content Delivery Network or CDN comes as big rescue if you want scale
website. CDN helps you to serve all your static and dynamic assets through its
servers across the world. Even if traffic is increasing exponentially, CDN makes
sure that all requests are distributed across the world with requests being served
from nearest servers. This also decreases load time. Your servers can focus on
other stuff.
Load Balancing – Load balancing is very effective in scaling a website. As the name
suggests, load balancing is a process of distributing network traffic across
different servers. In this way, if one server is free then load balancer will
direct traffic to that server decreasing the load on current servers. This process
is done by using couple of algorithms like round robin, IP hash etc.
Caching – Local Caching which involves storing external resources locally and
looking up next time when same resources are requested. Centralized Caching focuses
on loading data once and sharing it across multiple devices. All can connect to
same store and pull in resources, Redis can be using for this purpose
More servers – It’s a no-brainer. Bigger and better server always help in handling
more traffic
Reduce Bandwidth usage – Whenever your server receives a lot of traffic, it’s
important to decrease bandwidth usage. This effectively leads to increase in page
speed, as load on server decreases. This can be done by compressing your code and
other resources.

Ques:Javascript Find | JS Find | Javascript Array.Find()


Find an Item in JS Array? There are several ways to find an item in JS Array but
using Javascript Array.Find() seems to be the most optimal way to achieve that.
Let’s see how does Javascript Find function works:

JS Find function searches for the item in Javascript array and returns the first
item that satisfies the search criteria.
You might find Javascript developers using JS Filter method to find an item in an
array but it has a major drawback.
JS Filter function goes through all the items in JS Array and returns an array of
all items that meets the search criteria.
So, using JS Find Function or Javascript Array.Find(), we can avoid that and finish
our search as soon as we hit the first target.

Now, let’s focus on how can we implement Array.Find() or JS Find for any given
array:
var Array = ["john doe", "naomi kims", "dan jones", "ravi ks"];
Array.find(function(item){
return item === "john doe"
});
Now, if you try to do same with Array.Filter() over Javascript Find() then you
might have to do

var Array = ["john doe", "naomi kims", "dan jones", "ravi ks"];
Array.filter(function(item){
return item === "john doe"
})[0];
So, we can avoid extra iteration as well as step to access first element of JS
Array using Array.find().
But there might be scenarios when there is more than one record and you want all
records to be returned. In that case use, JS Filter over JS Find.
Questions related to javascript find method are sometimes asked in Javascript
Interview.
Here is an implementation of Array.find() in Javascript objects where it makes more
sense.
Suppose we have to find an object where age is 20.

var Array = [{
name: " John Doe",
age: 20
},
{
name: "Raavi",
age: 30
},
{
name: "K Shay",
age: 20
}];
Using Javascript Find(),
var Result = Array.find(function(item) {
return item.age === 20
})

console.log(Result.name) // logs John Doe (remember first result)


Javascript Find() is supported across all browsers except IE. For such cases we
need to write
the pollyfills of Array.Find() and JS Find() will work everywhere.
You can also use certain libraries that provide polyfills for such
functions(Array.find()).

Ques: Add(1)(2)(3)…(n)() in Javascript | Sum(1,2)(3,4) | Currying | Javascript


Interview | Walmart
Write a JS function to implement Add(1)(2)(3)…(n)() or just add(1)(2)(3) that
returns 6 or may be sum(1,2)(3,4) that returns 10? This is a quite famous
Javascript interview question with several complex variations. Goal is to return
the sum of all arguments with a sequence of function calls. This concept of calling
a sequence of functions is called as Currying. I was asked this question in
Walmart/Makemytrip interview for Front end engineer role.

Sum(1)(2)(3)
Currying: Currying is basically transforming sum(1,2,3) into sum(1)(2)(3). I will
be covering currying in details in another post. Let’s look at the code:
Case 1: add(1)(2)(3)
It’s basically a sequence of functions with single argument. So our approach is to
return a function which in turn returns another function to accept next argument.
function add(a){
return function(b){
return function(c){
return a+b+c
}
}
}

Case 2: add(1)(2)(3)…(n)()
It’s basically a sequence of n+1 functions with single argument except the last
one. So our approach is to return a function which in turn returns another function
to accept next argument and so on till the last argument doesn’t exist.
function add(a) {
return function(b){
if(b){
return add(a+b)
}
return a
}
}
Case 3: sum(1,2)(3,4)
So, this is similar as above just that we are accepting two arguments in single
call. So, we need to add the arguments. Let’s look at the code:
function sum(a,b) {
return function(c,d){
return a+b+c+d
}
}

So, it’s making sense now. Now let’s raise the complexity.
Case 4: add(1,2..n)(5,6…n)…(n)()
Now in this case, everything is infinite. We already know infinite currying, let’s
focus on infinite arguments.
function add(...args) {
let a = args.reduce((a, b) => a + b, 0)
return function(...args){
let b = args.reduce((a, b) => a + b, 0)
if(b){
return add(a+b)
}
return a
}
}
So this is complex, right? You won’t be asked this question during your initial
years of Javascript Interview but you never know. So, what’s happening here is, we
are using inbuilt rest operators to take infinite arguments and then calculating
the sum of all arguments. Rest remains the same as case 2.

Ques: How to flatten a nested array in JS | Recursion | Javascript Interview | 1


How to flatten a nested array? I have been asked this question number of times
during my Javascript Interviews. You aren’t allowed to use the inbuilt Flat() in
Javascript Interviews.
How to flatten a nested array in JS | Javascript Interview
Array = [1,2,[3,4,[5,6],7],8,[9,[10,11]]]
Required output: [1,2,3,4,5,6,7,8,9,10,11]
We are going to write a recursive function i.e the function which calls itself to
flatten a nested array
We are going to loop through the array and check if the item is an array
If it is, we are going to loop through that item by passing that to the function
If it is not then we will push it to another array(blank initially)
Let's look at the code:

function Flat(myArray, newArray=[]){


for(let i = 0; i < myArray.length; i++) {
if(Array.isArray(myArray[i])){
// We are using isArray method of Array Prototype
Flat(myArray[i],newArray) // call the function again with the current array in
myArray[i];
}
else {
newArray.push(myArray[i])
// if myArray[i] isn't a array, push it to new array
}
}
return newArray
}

Now, this solution is intended for people with less than 1 YOE in Javascript. If
you have better understanding of Javascript, you can go ahead with the below
solution in order to flatten a nested array in Javascript:

function flat(myArray, newArray=[])


{
myArray.forEach((item) => (Array.isArray(item))?flat(item, newArray)
:newArray.push(item))
return newArray
}

Ques: OYO questions:


Closures in Javascript
If a == 1 && a == 2 && a == 3, what will be the value of a?
Anonymous functions
Settimeout inside for loop running 1 to 5? What will it print and how can we change
it to print 1 to 5? Use of let and IIFE.
Debounce and Throttle code
Webpack Dependency Graph
React Reconciliation
HTTP vs HTTPS
Prototypal Chaining
ES6 code to ES5 etc

Ques: Makemytrip
Iterating though nested objects and listing all the key value pairs. You have to
check the type of value and when it’s a object go deeper till you find the last key
value pair, otherwise just list the key value pair.
Writing a function that can memoize any function including recursive ones.
Transform a function to give certain output, it was based on IIFE concept.
Deep vs Shallow copy of Javascript Object
Throttle based question on optimising search.
Few output questions based on Closure, Higher Order Functions and Hoisting etc
UI Mockup
Tech Stack and Architecture of the application. Local states/Redux/ContextApi
states.
Total functions and code for each function.
Caching, PWA, background sync implementation, scaling.
Redux vs ContextApi vs Passing Props
Call Stack related questions
How will setTimeOut respond inside for loop and using IIFE and let inside it.
Advanced JS: Interviewer needed in depth answers. He told me that i should have
more knowledge as i am a senior software engineer but i was a software engineer
with 2 Yrs working experience at the time of Interview.
What are Generator Function(function*) and output questions based on it(yield,
next).
Callback to Promise conversion and vice versa.
Logic behind Pure Components in React, useMemo vs useCallback, how does react
implement these methods.
Async Await with Promise based output questions including nesting etc

Ques: Flipkart
Prototypal Inheritance in Javscript and how does prototype chain works?
What is a reduce function in Javascript. How to write a polyfill of a reduce
function? He wanted me to cover all cases while writing a pollyfill of reduce. You
can check MDN documentation for that.
How does Redux Saga works, what problem it solves and how can we achieve our goals
without redux saga?
How does closures work?
How will i design a calendar? What controls will i make? What events will i attach?
How will i render a numbers in calendar for every month? And a bunch of other
calendar related questions. I had to write functions, CSS layouts etc. I nailed
this round.
Interviewer asked some popular Javascript Interview Questions.

3. Data Structures and Problem Solving: Interviewer was a back end engineer i
guess as he was not familiar of in built JS methods.
Given a string, reverse only the alphabets keeping rest of the character at the
same place
Find all pairs in an array where sum is equal to a certain number(You can create a
JS Object and then directly look for sum-num in Object)
I don’t remember as it has been a while since interview happened but it was a DP
based question(You have to use memoization to solve this)

Ques: wallmart
Questions based on currying with 4 different variations. I have written a detailed
post on it. ADD(1)(2)(3)…(N)() IN JAVASCRIPT | SUM(1,2)(3,4) | CURRYING | This
question went on for a long time as interviewer kept coming up with difficult
variations.
How does closures work in Javacript? Closure based output questions.
Drawing shapes in CSS using box modal? You can approach this by using borders to
create shapes like triangle etc.
Inheritance in Javascript and how to implement it in ES5?
Scope based questions(value of “this” under certain conditions) etc.
Virtual DOM and Shadow DOM implementation. How does react reconciliation works?

Ques: What is ECMAScript?


ECMAScript (/ˈɛkməskrɪpt/) (or ES)[1] is a JavaScript standard meant to ensure the
interoperability of web pages across different web browsers.[2] It is standardised
by Ecma International according to the document ECMA-262. ECMAScript is commonly
used for client-side scripting on the World Wide Web, and it is increasingly being
used for writing server applications and services using Node.js.

Ques: What is the value of ans[0] in the below script?


const ans = ['jacket', 't-shirt'];
ans.length = 0;
ans[0]; // => ???
Answer: The length method used for arrays has a unique property that deletes the
array values between the old and the new length. As the ans.length is set to 0, all
the values in the array have been deleted. Hence the final answer is undefined.
Ans[0] is undefined as the array has been emptied.

Ques:Difference between Object.freeze() and const in JavaScript


Ans:const: The const keyword creates a read-only reference to a value. Variables
created by the const keyword are immutable. In other words, you can’t reassign them
to different values. Trying to reassign a constant variable will result in a
TypeError.
The const keyword ensures that the variable created is read-only. But It doesn’t
mean that the actual value to which the const variable reference is immutable. Even
though the person variable is constant. However, you can change the value of its
property. But you cannot reassign a different value to the person constant.
const person = {
name: "Geeksforgeeks"
};

// No TypeError
person.name = "gfg";
console.log(person.name);

Object.freeze() method: If you want the value of the person object to be immutable,
you have to freeze it by using the Object.freeze() method.
<script>
const person = Object.freeze({name: "Geeksforgeeks"});

// TypeError
person.name = "gfg";
</script>
The Object.freeze() method is shallow, meaning that it can freeze the properties of
the object, not the objects referenced by the properties.
Example 2:
const person = Object.freeze({
name: 'Geeksforgeeks',
address: {
city:"Noida"
}
});
But the person.address object is not immutable, you can add a new property to the
person.address object as follows:
// No TypeError
person.address.country = "India";
Conclusion:
const prevents reassignment.
Object.freeze() prevents mutability.

Ques:What is the Javascript Event Delegation Model?


Answer: Event delegation allows us to attach a single event listener to a parent
element, which will work for all descendants matching a selector, whether those
descendants exist now or are added in the future

Ques:How to empty an array in JavaScript?


Answer:
There are various methods to do so. Let’s discuss each one of them.
Suppose a[] = [1,2,3,4,5,6];
Method 1:
We can set the value of a [] = [];
The above method assigns a new array to the variable a, deleting its previous
values.
Method 2:
We are aware of the JS array.length function, this function deletes the values of
the array within a defined value.
We can empty an array ‘a’ by simply assigning,
a.length = 0;
Method 3:
We can use a pop() method to delete all the elements of the array till the
array.length is true.
while(a.length)
{
a.pop()
}
Method 4:
The splice method in array.splice(cuts) the array from a defined initial value till
the final value.
It requires two parameters (initial, final) values from the user.
In the above example, to delete all the elements of an array, we can write the
following code,
a.splice(0,a.length);

Ques:What is Strict mode in JS?


Answer: It is a stricter or secured version of ordinary javascript language that
produces errors for those mistakes handled silently otherwise. It was introduced in
ECMAScript 5.
For example :
In normal Js, if we try to run the below commands
a=10;
console.log(a);
We will not get an error as the compiler would by default consider ‘a’ as a ‘var’
data type.
But if we use strict Js, we would get an error if we try to run the above code
stating a is not defined.

Ques: JavaScript Array splice vs slice


Ans: Splice and Slice both are Javascript Array functions.
Splice vs Slice
The splice() method returns the removed item(s) in an array and slice() method
returns the selected element(s) in an array, as a new array object.
The splice() method changes the original array and slice() method doesn’t change
the original array.
The splice() method can take n number of arguments and slice() method takes 2
arguments.
Splice with Example
Argument 1: Index, Required. An integer that specifies at what position to add
/remove items, Use negative values to specify the position from the end of the
array.
Argument 2: Optional. The number of items to be removed. If set to 0(zero), no
items will be removed. And if not passed, all item(s) from provided index will be
removed.
Argument 3…n: Optional. The new item(s) to be added to the array.
var array=[1,2,3,4,5];
console.log(array.splice(2));
// shows [3, 4, 5], returned removed item(s) as a new array object.
console.log(array);
// shows [1, 2], original array altered.
var array2=[6,7,8,9,0];
console.log(array2.splice(2,1));
// shows [8]
console.log(array2.splice(2,0));
//shows [] , as no item(s) removed.
console.log(array2);
// shows [6,7,9,0]
Expand snippet
Slice with Example
Argument 1: Required. An integer that specifies where to start the selection (The
first element has an index of 0). Use negative numbers to select from the end of an
array.
Argument 2: Optional. An integer that specifies where to end the selection but does
not include. If omitted, all elements from the start position and to the end of the
array will be selected. Use negative numbers to select from the end of an array.
var array=[1,2,3,4,5]
console.log(array.slice(2));
// shows [3, 4, 5], returned selected element(s).
console.log(array.slice(-2));
// shows [4, 5], returned selected element(s).
console.log(array);
// shows [1, 2, 3, 4, 5], original array remains intact.
var array2=[6,7,8,9,0];
console.log(array2.slice(2,4));
// shows [8, 9]
console.log(array2.slice(-2,4));
// shows [9]
console.log(array2.slice(-3,-1));
// shows [8, 9]
console.log(array2);
// shows [6, 7, 8, 9, 0]

Slice ( )
The slice( ) method copies a given part of an array and returns that copied part as
a new array. It doesn’t change the original array.

array.slice(from, until);

From: Slice the array starting from an element index


Until: Slice the array until another element index
For example, I want to slice the first three elements from the array above. Since
the first element of an array is always indexed at 0, I start slicing “from”0.
array.slice(0, until);
Now here is the tricky part. When I want to slice the first three elements, I must
give the until parameter as 3. The slice( ) method doesn’t include the last given
element.
array[0] --> 1 // included
array[1] --> 2 // included
array[2] --> 3 // included
array[3] --> "hello world" // not included
This can create some confusion. That’s why I call the second parameter “until”.
let newArray = array.slice(0, 3); // Return value is also an array
Finally, I assign the sliced Array to the newArray variable. Now let’s see the
result:
Slice array and assign the members to newArray
newArray variable is an array now, and the original one remains the same
Important Note: the Slice( ) method can also be used for strings.
let arr = [1,2,3,"hello",4.12,true];
let newArr = arr.spice(0,3);
new Arr => [1,2,3]
arr => [1,2,3,"hello",4.12,true];

Splice ( )
The name of this function is very similar to slice( ). This naming similarity often
confuses developers. The splice( ) method changes an array, by adding or removing
elements from it. Let’s see how to add and remove elements with splice( ):
Removing Elements
For removing elements, we need to give the index parameter, and the number of
elements to be removed:
array.splice(index, number of elements);
Index is the starting point for removing elements. Elements which have a smaller
index number from the given index won’t be removed:
array.splice(2); // Every element starting from index 2, will be removed
If we don’t define the second parameter, every element starting from the given
index will be removed from the array:
let arr = [1,2,3,"hello",4.12,true];
arr.splice(2);
//[3,"hello",4.12,true]
arr now => [1,2]
As a second example, I give the second parameter as 1, so elements starting from
index 2 will be removed one by one each time we call the splice ( )method:
array.splice(2, 1);
Arr at beginning
let arr = [1,2,3,"hello",4.12,true];
After 1st call:
arr
[1,2,"hello",4.12,true]
3 is removed so “hello world” has now index 2
After 2nd call
arr
[1,2,4.12,true]
This time, “hello world” is removed as index: 2
This can continue until there is no index 2 anymore.

Adding Elements
For adding elements, we need to give them as the 3rd, 4th, 5th parameter (depends
on how many to add) to the splice ( ) method:
array.splice(index, number of elements, element, element);
As an example, I’m adding a and b in the very beginning of the array and I remove
nothing:
array.splice(0, 0, 'a', 'b');
arr.splice(0,0,"a","b");
[]
arr
["a","b",1,2,3,"hello",4.12,true]
a and b added to the beginning of array, no elements removed

Split ( )
Slice( ) and splice( ) methods are for arrays. The split( ) method is used for
strings. It divides a string into substrings and returns them as an array. It takes
2 parameters, and both are optional.
string.split(separator, limit);
Separator: Defines how to split a string… by a comma, character etc.
Limit: Limits the number of splits with a given number
The split( ) method doesn’t work directly for arrays. However, we can first convert
the elements of our array to a string, then we can use the split( ) method.
Let’s see how it works.
Firstly, we convert our array to a string with toString( ) method:
let myString = array.toString();
let mystring = arr.toString();
undefined
myString
"1,2,3,"hello",4.12,true"
Now let’s split myString by commas, limit them to three substrings, and return them
as an array:
let newArray = myString.split(",", 3);
["1","2","3"]
Only the first 3 elements are returned
As we can see, myString is split by commas. Since we limit split to 3, only the
first 3 elements are returned.
NOTE: If we have a usage like this: array.split(""); then each character of the
string will be divided as substrings:
Each character split one by one

Ques: Arrow functions?


Ans: An arrow function expression is a compact alternative to a traditional
function expression, but is limited and can't be used in all situations.
Basic syntax
One param. With simple expression return is not needed:
param => expression

Multiple params require parentheses. With simple expression return is not needed:
(param1, paramN) => expression

Multiline statements require body braces and return:


param => {
let a = 1;
return a + param;
}

Differences & Limitations:


>Does not have its own bindings to this or super, and should not be used as
methods.
>Does not have new.target keyword.
>Not suitable for call, apply and bind methods, which generally rely on
establishing a scope.
>Can not be used as constructors.
>Can not use yield, within its body.

Arrow functions used as methods


As stated previously, arrow function expressions are best suited for non-method
functions. Let's see what happens when we try to use them as methods:
'use strict';
var obj = { // does not create a new scope
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log(this.i, this);
}
}
obj.b(); // prints undefined, Window {...} (or the global object)
obj.c(); // prints 10, Object {...}

Arrow functions do not have their own this. Another example involving
Object.defineProperty():
'use strict';
var obj = {
a: 10
};
Object.defineProperty(obj, 'b', {
get: () => {
console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...}
(or the global object)
return this.a + 10; // represents global object 'Window', therefore 'this.a'
returns 'undefined'
}
});

call, apply and bind


The call, apply and bind methods are NOT suitable for Arrow functions -- as they
were designed to allow methods to execute within different scopes -- because Arrow
functions establish "this" based on the scope the Arrow function is defined within.
For example call, apply and bind work as expected with Traditional functions,
because we establish the scope for each of the methods:
// ----------------------
// Traditional Example
// ----------------------
// A simplistic object with its very own "this".
var obj = {
num: 100
}

// Setting "num" on window to show how it is NOT used.


window.num = 2020; // yikes!

// A simple traditional function to operate on "this"


var add = function (a, b, c) {
return this.num + a + b + c;
}

// call
var result = add.call(obj, 1, 2, 3) // establishing the scope as "obj"
console.log(result) // result 106

// apply
const arr = [1, 2, 3]
var result = add.apply(obj, arr) // establishing the scope as "obj"
console.log(result) // result 106

// bind
var result = add.bind(obj) // establishing the scope as "obj"
console.log(result(1, 2, 3)) // result 106

With Arrow functions, since our add function is essentially created on the window
(global) scope, it will assume this is the window.
// ----------------------
// Arrow Example
// ----------------------

// A simplistic object with its very own "this".


var obj = {
num: 100
}

// Setting "num" on window to show how it gets picked up.


window.num = 2020; // yikes!

// Arrow Function
var add = (a, b, c) => this.num + a + b + c;

// call
console.log(add.call(obj, 1, 2, 3)) // result 2026

// apply
const arr = [1, 2, 3]
console.log(add.apply(obj, arr)) // result 2026

// bind
const bound = add.bind(obj)
console.log(bound(1, 2, 3)) // result 2026
Perhaps the greatest benefit of using Arrow functions is with DOM-level methods
(setTimeout, setInterval, addEventListener) that usually required some kind of
closure, call, apply or bind to ensure the function executed in the proper scope.

Traditional Example:

var obj = {
count : 10,
doSomethingLater : function (){
setTimeout(function(){ // the function executes on the window scope
this.count++;
console.log(this.count);
}, 300);
}
}

obj.doSomethingLater(); // console prints "NaN", because the property "count" is


not in the window scope.
Arrow Example:

var obj = {
count : 10,
doSomethingLater : function(){
// The traditional function binds "this" to the "obj" context.
setTimeout( () => {
// Since the arrow function doesn't have its own binding and
// setTimeout (as a function call) doesn't create a binding
// itself, the "obj" context of the traditional function will
// be used within.
this.count++;
console.log(this.count);
}, 300);
}
}

obj.doSomethingLater();
No binding of arguments
Arrow functions do not have their own arguments object. Thus, in this example,
arguments is a reference to the arguments of the enclosing scope:

var arguments = [1, 2, 3];


var arr = () => arguments[0];

arr(); // 1

function foo(n) {
var f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0]
is n
return f();
}

foo(3); // 3 + 3 = 6
In most cases, using rest parameters is a good alternative to using an arguments
object.

function foo(n) {
var f = (...args) => args[0] + n;
return f(10);
}

foo(1); // 11
Use of the new operator
Arrow functions cannot be used as constructors and will throw an error when used
with new.

var Foo = () => {};


var foo = new Foo(); // TypeError: Foo is not a constructor
Use of prototype property
Arrow functions do not have a prototype property.

var Foo = () => {};


console.log(Foo.prototype); // undefined
Use of the yield keyword
The yield keyword may not be used in an arrow function's body (except when
permitted within functions further nested within it). As a consequence, arrow
functions cannot be used as generators.

Ques: Arrow Functions vs. Regular Functions in JavaScript


Learn when and when not to use the arrow function
Today, there are two common methods of declaring a function in JavaScript: Arrow
functions and Regular functions. On most occasions, we use both these functions
without considering their suitability or differences.
However, these functions differ in many significant ways, and we can’t replace one
with another.
So in this article, I will explore 5 of these key differences in detail.
1. “this” Keyword
this keyword is one of the most used keywords in JavaScript. But when it comes to
regular functions and arrow functions, it behaves in entirely different ways.
In regular function, this changes according to the way that function is invoked.
Simple Invocation: this equals the global object or maybe undefined if you are
using strict mode.
Method Invocation: this equals the object that owns the method.
Indirect Invocation: this equals the first argument.
Constructor Invocation: this equals the newly created instance.
// Simple Invocation
function simpleInvocation() {
console.log(this);
}
simpleInvocatoin(); // logs global object
--------------------------------------------------------------------
// Method Invocation
const methodInvocation= {
method() {
console.log(this);
}
};
methodInvocation.method(); // logs methodInvocation object
--------------------------------------------------------------------
// Indirect Invocation
const context = { value1: 'A', value2: 'B' };
function indirectInvocation() {
console.log(this);
}
indirectInvocation.call(context); // logs { value1: 'A' }
indirectInvocation.apply(context); // logs { value1: 'A' }
--------------------------------------------------------------------
// Constructor Invocation
function constructorInvocation() {
console.log(this);
}

new constructorInvocation(); // logs an instance of constructorInvocation


But, in the arrow functions, the behavior of this changes completely.

Arrow functions don't have their own “this”, and they don’t redefine the value of
“this ”within the function.

Regardless of how you execute arrow functions, this inside an arrow function always
refers to this from the outer context. This means that this keyword is lexically
bound in arrow functions.
To understand it better, let’s consider the above example of Method Invocation with
an arrow function to see the difference:
var variable = “Global Level Variable”;
let myObject = {
variable: “Object Level Variable”,
arrowFunction:() => {
console.log(this.variable);
},
regularFunction(){
console.log(this.variable);
}
};
myObject.arrowFunction(); // Print Global Level Variable
myObject.regularFunction(); // Print Object Level Variable

This behavior of arrow functions makes them really useful when using callbacks
inside methods.

You don't need to use workarounds like const self = this or callback.bind(this)
with arrow functions, and it prevents any mistakes that can be caused by the use of
this within callbacks.
2. Arguments Object.
In regular JavaScript functions, arguments keywords can be used to access the
passed arguments when the function is invoked.
For example, If I call a function with 3 arguments, I will be able to access them
using arguments keyword like this:
function exampleFunction() {
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
exampleFunction(1,2,3)
Output:
1
2
3

But, arrow functions do not have their own arguments and it uses the arguments from
the outer function.
The behavior of the arguments keyword within an arrow function is similar to the
behavior of this keyword we discussed earlier, and it is resolved lexically.
let exampleFunction = {
printArguments : () => {
console.log(arguments);
}
}
exampleFunction.printArguments(1,2,3)
Output: Reference error: argumensts is not defined

However, if you want to access arguments directly in an arrow function, you can use
the rest parameters feature:
let exampleFunction = {
printArguments : (…args) => {
console.log(…args);
}
}
exampleFunction.printArguments(1,2,3);
Output: 1 2 3

3. Constructors / “new” keyword


As well know, we can easily construct objects with regular functions. We just need
to invoke the function with the new keyword.
function Article(topic) {
this.topic= topic;
}

const article= new Article('JavaScript');


Above gives type error, Article is not a constructor.
However, arrow functions can not be used as constructors.
Since this keyword is resolved lexically in arrow functions, we cant use it to
construct objects.

4. Implicit return
In regular functions, we can use the return keyword to return any value from a
function. If we don’t return anything, the function will implicitly return
undefined.
function exampleFunction() {
return 10;
}
exampleFunction(); // output -> 10
--------------------------------------------------------------------
function exampleFunction() {
var number = 10;
}
exampleFunction(); // output -> undefined
--------------------------------------------------------------------
function exampleFunction() {
var number = 10;
return;
}
exampleFunction(); // output -> undefined
Arrow functions behave in the same way when returning values. But there is one
advantage you can take from it.
If the arrow function contains one expression, you can omit the curly braces, and
then the expression will be implicitly returned.
const addOne = (number) => number + 1;
addOne(10);
Output: 11

Final Thoughts
In this article, I have discussed some significant differences between regular
functions and arrow functions in JavaScript. Based on the results and advantages,
you might feel that arrow functions are better than regular functions.
But, that’s not true for all cases, and there are some situations you should avoid
using arrow functions.
It is recommended to use regular functions when dealing with Promises, Callback
functions with dynamic context, and Object methods.
So, as a developer, you should understand these differences to identify the best
matching function type for your requirement.

Ques:JavaScript Constructor Function


Introduction to JavaScript constructor functions
In the JavaScript objects tutorial, you learned how to use the object literal
syntax to create a new object:

let person = {
firstName: 'John',
lastName: 'Doe'
};
Code language: JavaScript (javascript)
In practice, you often need to create many similar objects like a list of persons.

To do this, you can use a constructor function to define a custom type and the new
operator to create multiple objects from this type.

Technically speaking, a constructor function is a regular function with the


following convention:

The name of a constructor function starts with a capital letter like Person,
Document, etc.
A constructor function should be called only with the new operator.
Note that ES6 introduces the class keyword that allows you to define a custom type.
And classes are just syntactic sugar over the constructor functions with some
enhancements.

The following example defines a constructor function called Person:


function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Code language: JavaScript (javascript)
As you can see, the Person is the same as a regular function except that its name
starts with the capital letter P.

To create a new instance of the Person, you use the new operator:

let person = new Person('John','Doe');


Code language: JavaScript (javascript)
Basically, the new operator does the following:

Create a new empty object and assign it to this.


Assign the arguments 'John' and 'Doe' to the firstName and lastName properties.
Return the this value.
It’s functionally equivalent to the following:

function Person(firstName, lastName) {


// this = {};

// add properties to this


this.firstName = firstName;
this.lastName = lastName;

// return this;
}
Code language: JavaScript (javascript)
Therefore, the following statement:

let person = new Person('John','Doe');


Code language: JavaScript (javascript)
… returns the same result as the following statement:

let person = {
firstName: 'John',
lastName: 'Doe'
};
Code language: JavaScript (javascript)
However, the constructor function Person allows you to create multiple similar
objects. For example:

let person1 = new Person('Jane','Doe')


let person2 = new Person('James','Smith')
Code language: JavaScript (javascript)
Adding methods to JavaScript constructor functions
An object may have methods that manipulate its data. To add a method to an object
created via the constructor function, you can use the this keyword. For example:

function Person(firstName, lastName) {


this.firstName = firstName;
this.lastName = lastName;

this.getFullName = function () {
return this.firstName + " " + this.lastName;
};
}
Code language: JavaScript (javascript)
Now, you can create a new Person object and invoke the getFullName() method:

let person = new Person("John", "Doe");


console.log(person.getFullName());
Code language: JavaScript (javascript)
Output:

John Doe
The problem with the constructor function is that when you create multiple
instances of the Person, the this.getFullName() is duplicated in every instance.
This is not memory efficient.

To resolve this, you can use the prototype so that all instances of a custom type
can share the same method.

Returning from constructor functions


Typically, a constructor function implicitly returns this that set to the newly
created object. But if it has a return statement, then here’s the rule:

If return is called with an object, the constructor function returns that object
instead of this.
If return is called with a value other than an object, it’s ignored.
Calling a constructor function without the new keyword
It’s possible to call a constructor function without the new keyword like this:

let person = Person('John','Doe');


Code language: JavaScript (javascript)
In this case, the Person just executes like a regular function. Therefore, the this
inside the Person function doesn’t bound to the person variable but the global
object.

If you attempt to access the firstName or lastName property, you’ll get an error:

console.log(person.firstName);
Code language: CSS (css)
Error:

TypeError: Cannot read property 'firstName' of undefined


Code language: JavaScript (javascript)
Similarly, you cannot access the getFullName() method since it’s bound to the
global object.

person.getFullName();
Code language: CSS (css)
Error:

TypeError: Cannot read property 'getFullName' of undefined


Code language: JavaScript (javascript)
To prevent a constructor function to be invoked without the new keyword, ES6
introduced the new.target property.

If a constructor function is called with the new keyword, the new.target returns a
reference to the function. Otherwise, it returns undefined.

Let’s show the value of the new.target to the console inside the Person function:

function Person(firstName, lastName) {


console.log(new.target);
this.firstName = firstName;
this.lastName = lastName;

this.getFullName = function () {
return this.firstName + " " + this.lastName;
};
}
Code language: JavaScript (javascript)
The following returns undefined because the Person constructor function is called
like a regular function:

let person = Person("John", "Doe");


Code language: JavaScript (javascript)
Output:

undefined
Code language: JavaScript (javascript)
However, the following returns a reference to the Person function because it’s
called with the new keyword:

let person = new Person("John", "Doe");


Code language: JavaScript (javascript)
Output:

[Function: Person]
Code language: JSON / JSON with Comments (json)
By leveraging the new.target, you can force users of the constructor function to
call it with the new keyword. And you can throw an error if they don’t do so like
this:

function Person(firstName, lastName) {


if (!new.target) {
throw Error("Cannot be called without the new keyword");
}

this.firstName = firstName;
this.lastName = lastName;
}
Code language: JavaScript (javascript)
Alternatively, you can make the syntax more flexible by creating a new Person
object if the users of the constructor function don’t use the new keyword:

function Person(firstName, lastName) {


if (!new.target) {
return new Person(firstName, lastName);
}

this.firstName = firstName;
this.lastName = lastName;
}

let person = Person("John", "Doe");

console.log(person.firstName);
Code language: JavaScript (javascript)
This pattern is often used in JavaScript libraries and frameworks to make the
syntax more flexible.
Summary
JavaScript constructor function is a regular function used to create multiple
similar objects.

Ques: What is babel?


Ans: it takes moder jS and compile it to code that is understandable in diff
environments. Babel is build into plugin System that parses your modern javascript
into AST and rewrite it into a version that can be interpretted by browser.
preset for babel: npm install babel-preset-env
In .babelrc you can set what level of compatibility you need for the target that
you intent to support and babel will automatically install the transformation
plugins.Ex: to transform to last 2 releases of all the major browsers.
in .babelrc file
{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions"]
}
}]
]
}
You can add this config in package.json file as well or add it in webpack config

Ques: Node Js Event loop


Ans: What is the Event Loop?
The event loop is what allows Node.js to perform non-blocking I/O operations —
despite the fact that JavaScript is single-threaded — by offloading operations to
the system kernel whenever possible.

Since most modern kernels are multi-threaded, they can handle multiple operations
executing in the background. When one of these operations completes, the kernel
tells Node.js so that the appropriate callback may be added to the poll queue to
eventually be executed.

Phases of event loop


Poll
|
v
(process.nextTick())
|
v
Check
|
v
(process.nextTick())
|
v
close callbacks
|
v
(process.nextTick())
|
v
timers
|
v
(process.nextTick())
|
v
pending callbacks
|
v
(process.nextTick())
|
v
idle prepare
|
v
(process.nextTick())
|
v
back to poll

Poll phase: All the synchronous JavaScript code you write is executed in the poll
phase of the event loop.
console.log(1);
console.log(2);
O/p: 1 & 2

Timers phase: This phase executes callback scheduled by setTimeout() and


setInterval()
setTimeout(() => {
console.log(2);
});
console.log(1);
so during poll phase setTimeout and console is executed and setTimeout callbacks in
registered and will come to timer queue after time specified and will be executed
there once we reach to timer phase.
Timer phase uses fifo queue mechanism to queue multiple callbacks to be executed
single iteration of event loop. So settimeout with time 0 does not ensure that
callback will be executed immediately possibly due to long queue of callback.

Check phase: setImmediate() callbacks are executed here. Callback scheduled by


setImmediate will be executed in check phase which is run immediately after the
poll phase. In check phase it will find the queue of callbacks that will get
executed.
setImmediate(()=> {
console.log(2);
});
console.log(1);
O/p: 1 & 2

Any callback provided to process.nextTick() get registered in the nextTick queue of


the next phase. So nextTick queue is executed after and before each phase.
setTimeout(()=>{
setTimeout(() => {
console.log('timeout'); // timer phase
});

setImmediate(() => {
console.log('immediate'); // check phase
});

process.nextTick(() => {
console.log('nextTick'); //
});

console.log('1'); // poll phase


console.log('2'); // poll phase
});
Output:
1
2
nextTick
immediate
timeout

Ques: setImmediate() vs setTimeout()


setImmediate() and setTimeout() are similar, but behave in different ways depending
on when they are called.

setImmediate() is designed to execute a script once the current poll phase


completes.
setTimeout() schedules a script to be run after a minimum threshold in ms has
elapsed.
The order in which the timers are executed will vary depending on the context in
which they are called. If both are called from within the main module, then timing
will be bound by the performance of the process (which can be impacted by other
applications running on the machine). For example, if we run the following script
which is not within an I/O cycle (i.e. the main module), the order in which the two
timers are executed is non-deterministic, as it is bound by the performance of the
process:

// timeout_vs_immediate.js
setTimeout(() => {
console.log('timeout');
}, 0);

setImmediate(() => {
console.log('immediate');
});
$ node timeout_vs_immediate.js
timeout
immediate

$ node timeout_vs_immediate.js
immediate
timeout

However, if you move the two calls within an I/O cycle, the immediate callback is
always executed first:

// timeout_vs_immediate.js
const fs = require('fs');

fs.readFile(__filename, () => {
setTimeout(() => {
console.log('timeout'); //timer phase
}, 0);
setImmediate(() => {
console.log('immediate'); //check phase
});
console.log(1); //poll phase
});
$ node timeout_vs_immediate.js
immediate
timeout

$ node timeout_vs_immediate.js
immediate
timeout
The main advantage to using setImmediate() over setTimeout() is setImmediate() will
always be executed before any timers if scheduled within an I/O cycle or inside any
other callback, independently of how many timers are present.

Ques: process.nextTick()
Ans: You may have noticed that process.nextTick() was not displayed in the diagram,
even though it's a part of the asynchronous API. This is because process.nextTick()
is not technically part of the event loop. Instead, the nextTickQueue will be
processed after the current operation is completed, regardless of the current phase
of the event loop. Here, an operation is defined as a transition from the
underlying C/C++ handler, and handling the JavaScript that needs to be executed.
Looking back at our diagram, any time you call process.nextTick() in a given phase,
all callbacks passed to process.nextTick() will be resolved before the event loop
continues. This can create some bad situations because it allows you to "starve"
your I/O by making recursive process.nextTick() calls, which prevents the event
loop from reaching the poll phase.

Ques: process.nextTick() vs setImmediate()


We have two calls that are similar as far as users are concerned, but their names
are confusing.

process.nextTick() fires immediately on the same phase


setImmediate() fires on the following iteration or 'tick' of the event loop
In essence, the names should be swapped. process.nextTick() fires more immediately
than setImmediate(), but this is an artifact of the past which is unlikely to
change. Making this switch would break a large percentage of the packages on npm.
We recommend developers use setImmediate() in all cases because it's easier to
reason about.

Ques: Why use process.nextTick()?


Ans: There are two main reasons:
>Allow users to handle errors, cleanup any then unneeded resources, or perhaps try
the request again before the event loop continues.
>At times it's necessary to allow a callback to run after the call stack has
unwound but before the event loop continues.

Ques: JavaScript event loop vs Node Js Event Loop


Ans:In short, Yes, they are similar in certain ways. And also, Yes, they are also
different in certain implementation aspects.

The term “Event Loop” is a generic programming pattern. It describes a simple loop
which iterates through the results of completed events, and process them.
JavaScript/NodeJS event loops are no different.
When JavaScript applications run, they fire various events, and these events will
cause corresponding event handlers to be enqueued for processing. The event loop
continuously watches for any queued event handlers and will process them
accordingly.
Both the browser and NodeJS implements an asynchronous event-driven pattern with
JavaScript. However, the “Events”, in a browser’s context, are user interactions on
web pages (e.g, clicks, mouse movements, keyboard events etc.), but in Node’s
context, events are asynchronous server-side operations (e.g, File I/O access,
Network I/O etc.). Due to this difference of needs, Chrome and Node have different
Event Loop implementations, though they share the same V8 JavaScript engine to run
JavaScript.

Since “the event loop” is nothing but a programming pattern, V8 allows the ability
to plug-in an external event loop implementation to work with its JavaScript
runtime. Using this flexibility, the Chrome browser uses libevent as its event loop
implementation, and NodeJS uses libuv to implement the event loop. Therefore,
chrome’s event loop and NodeJS’s event loop are based on two different libraries
and which have differences, but they also share the similarities of the common
“Event Loop” programming pattern.

Micro-tasks vs Macro-tasks differences


What are microtasks and macrotasks? In short, Macro-tasks and Micro-tasks are two
types of asynchronous tasks. However, Micro-tasks have a higher priority compared
to Macro-tasks. An example of a micro-task is a promise callback. And a setTimeout
callback is an example of a macro-task

https://www.youtube.com/watch?v=ELNFqCOQhjs
Ques: What is a inline and block level elements in html
Ques: Diff between inline and inline block elements
Ques: What is total size of local storage.
Ques: What are the semantic elements in html
Ques: What is a box model
Ques: What is css specificity
Ques: In a div I have 10 divs, we want to show 5 div in a row each, how to do in
css
Ques: What is virtual DOM in react
Ques: Explain react class component life cycle
Ques: What is the use of shouldComponentUpdate method
Ques: Diff between react component and react.pure component
Ques: In react what are the methods in which we can write react setSate
Ques: what if I write setState in react.render method? (it will recursively
rerender itself - it will go to infinity lean and return error - execeeded stack)
Ques: What is higher order component
Ques: What is use of redux
Ques: In redux what connect method do
Ques: Remove duplicates from array
Ques: Get array of values from object
const x = {
a: 1,
b:2
}
Ans:
const xarr= [];
for (let i in x) {
xarr.push(x[i]);
}

Ques: Reverse string in js


Ans:
function reverse(s){
return s.split("").reverse().join("");
}

Ques:
const x = {
a: 1,
b:2,
getA() {
console.log(this.a);
},
getB() {
console.log(this.b);
}
}
what modification will you do to print both consoles using below statement
x.getA().getB();
Ans:
const x = {
a: 1,
b:2,
getA() {
console.log(this.a);
return this;
},
getB() {
console.log(this.b);
}
}

Ques: [1,2,3].print(); // it should print 1,2,3


Ans:
Array.prototype.print = () => {
let result = '';
for(let [i,elem] of this) {
if(i===this.length) {
result +=elem;
} else {
result += `${elem},`;
}
}
console.log(result);
}

Ques: Can (a==1 && a==2 && a==3) ever evaluate to true? If yes what will be value
of a.
The answer is — Yes
const a = {
num: 0,
valueOf: function() {
return this.num += 1
}
};
const equality = (a==1 && a==2 && a==3);
console.log(equality); // true
Reason: when you check loose equality with two different types of operators,
JavaScript will attempt to perform type coercion — it will attempt to coerce
(convert) the operands into a like/similar type.
In our equation: (a==1 && a==2 && a==3), JavaScript will attempt to coerce the
object a into a number prior to comparing them. When performing type coercion on an
object, JavaScript first attempts to call the valueOf() method.

Ques:What is the CSS box model?


The CSS box model as a whole applies to block boxes. Inline boxes use just some of
the behavior defined in the box model. The model defines how the different parts of
a box — margin, border, padding, and content — work together to create a box that
you can see on a page. To add some additional complexity, there is a standard and
an alternate box model.

Parts of a box
Making up a block box in CSS we have the:

Content box: The area where your content is displayed, which can be sized using
properties like width and height.
Padding box: The padding sits around the content as white space; its size can be
controlled using padding and related properties.
Border box: The border box wraps the content and any padding. Its size and style
can be controlled using border and related properties.
Margin box: The margin is the outermost layer, wrapping the content, padding, and
border as whitespace between this box and other elements. Its size can be
controlled using margin and related properties.
The below diagram shows these layers:

The standard CSS box model


In the standard box model, if you give a box a width and a height attribute, this
defines the width and height of the content box. Any padding and border is then
added to that width and height to get the total size taken up by the box. This is
shown in the image below.

If we assume that a box has the following CSS defining width, height, margin,
border, and padding:

.box {
width: 350px;
height: 150px;
margin: 10px;
padding: 25px;
border: 5px solid black;
}
Copy to Clipboard
The actual space taken up by the box will be 410px wide (350 + 25 + 25 + 5 + 5) and
210px high (150 + 25 + 25 + 5 + 5).

Showing the size of the box when the standard box model is being used.

Note: The margin is not counted towards the actual size of the box — sure, it
affects the total space that the box will take up on the page, but only the space
outside the box. The box's area stops at the border — it does not extend into the
margin.

Ques: HTML5 | Semantics


HTML tags are classified in two types.

Semantic
Non-Semantic
Semantic Elements: Semantic elements have meaningful names which tells about type
of content. For example header, footer, table, … etc. HTML5 introduces many
semantic elements as mentioned below which make the code easier to write and
understand for the developer as well as instructs the browser on how to treat them.
article: It contains independent content which doesnt require any other context.
aside: It is used to place content in a sidebar i.e. aside the existing content. It
is related to surrounding content.
details
figcaption: These are used to add an image in a web page with small description.
figure
footer
header:it is for the header of a section introductory of a page. There can be
multiple headers on a page.
main
mark
nav: It is used to define a set of navigation links in the form of navigation bar
or nav menu.
section
Article
Example: Blog Post, Newspaper Article etc.

Ques:HOW TO DEVELOPING AN EASILY SCALABLE EXPRESS SERVER


One of the most famous web frameworks for Node.js is Express, which is written in
Javascript and hosted inside a Node.js runtime environment.

In this second example, it is shown how to create an easily scalable Express server
and how to allow a single server process to take advantage of the cluster module
with a few lines of code.

var cluster = require('cluster');

if(cluster.isMaster) {
var numWorkers = require('os').cpus().length;

console.log('Master cluster setting up ' + numWorkers + ' workers...');

for(var i = 0; i < numWorkers; i++) {


cluster.fork();
}

cluster.on('online', function(worker) {
console.log('Worker ' + worker.process.pid + ' is online');
});

cluster.on('exit', function(worker, code, signal) {


console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and
signal: ' + signal);
console.log('Starting a new worker');
cluster.fork();
});

} else {
var app = require('express')();
app.all('/*', function(req, res) {res.send('process ' + process.pid + ' says
hello!').end();})

var server = app.listen(8000, function() {


console.log('Process ' + process.pid + ' is listening to all incoming requests');
});
}

GETTING MASTERS AND WORKERS TO COMMUNICATE


It is important to manage the exchange of messages between the parent processes and
their children in order to assign tasks or perform other operations.

To view the messages, set up a procedure that recognizes the message event for both
the master and worker side:

worker.on('message', function(message){
console.log(message);
});
Within the code, the worker object is the reference returned by the fork ()
method .

Now, switch to listening to messages by the master as follows :

process.on('message', function(message) {
console.log(message);
});

Messages can be strings or JSON objects. To send one, for example, from parent to
child process (from master to worker ), you can try the command:

worker.send('hello from the master');


To send the message in the opposite direction, write:

process.send('hello from worker with id: ' + process.pid);


To learn more about the content of messages, they could be considered as JSON
objects containing additional information. Here is an example:

worker.send({
type: 'task 1',
from: 'master',
data: {
// the data that you want to transfer
}
});

Ques: Spin up leight weight node js docker container


Ans:
create dir app
in app create file index.js
const app=require("express")();
app.get('/',(req,res)=> {
res.send("hello from node");
})
app.listen(9999,()=>console.log("listening from port 9999"));

Create docker file with name Dockerfile


From node:12
WORKDIR /home/node/app #this is path inside docker from where we want to run our
app
COPY app /home/node/app #this is copying our code from app directory of our machine
to /home/node/app directory of container
RUN npm install
CMD npm run app #app commans is added in package.json to start or app i.e app: node
index.js
EXPOSE 9999 #this is the port our application is listening on

Now after this in terminal create docker image


docker build -t nodeappimg . //dot is for current path
docker run --name nodeappcont -p 8080:9999 nodeappimg

now if we run in browser localhost:8080


it will show node app running

/***************************************
Property Descriptors Methods and Usage
Object.defineProperty(obj, propName, {} )
Object.defineProperties(obj, props)
Object.getOwnPropertyNames(obj)
Object.getOwnPropertyDescriptor(obj, prop)
Object.getOwnPropertyDescriptors(obj)
Object.keys(obj) - list of enumerable properties
Object.values(obj) - list of enumerable prop values
obj.propertyIsEnumerable(prop)
obj.hasOwnProperty(prop)
Objects can be
1. Extensible - new properties added
2. Frozen - props cannot be changed in any way
3. Sealed - props can't be deleted or configured
but are still writable
Object PROPERTIES can be
1. Writable - change the value
2. Enumerable - seen through a for...in loop
3. Configurable - change the property descriptors
Object.isExtensible(obj)
Object.isFrozen(obj)
Object.isSealed(obj)
Object.preventExtensions(obj)
Object.freeze(obj)
Object.seal(obj)
Descriptor Groups
DATA ACCESSOR
value get
writable set
configurable configurable
enumerable enumerable
****************************************/
let log = console.log;
let obj = {
name: 'Bob',
age: 45
};
Object.defineProperty(obj, 'test', {
value: 'Shagadelic',
writable: true,
configurable: true,
enumerable: false
} );

Object.defineProperty(obj, 'frank', {
configurable:true,
enumerable: true,
get: () => this.value,
set: (_val) => {
this.value = _val + " baby!";
}
});

for( let prop in obj){


log(prop);
}
log( obj, obj.test, obj.frank );
obj.frank = 'Shagadelic';
log(obj.frank);

Ques: When to use GraphQL vs REST API


Ans:
Use Case:
Public ad-hoc API that you can't predict how it will be used: GraphQL: Yes Rest: No
Spcific and well defined use case API: GraphQL: No REST:yes
Simple api that serves one client GraphQA: no REST: yes
Enterprise API (new york times) GraphQA: yes REST: no
Well defined schema GraphQA: yes REST: no

Ques: Websocket Pros and cons


Ans:
Pros:
>Full duplex (No Polling)
>Http Compatible
>Firewall Friendly(standard)

Cons:
>Proxying is tricky
>L/7 Load balancer challanginf (Timeouts)
>Stateful, difficult to horizontally scale

Ques: What is pipe and compose in js and its polyfill for compose
Ans :- https://lnkd.in/gf2QXtmG

Ques:What is server side rendering and its pros and cons


Ans :- https://lnkd.in/gCXxKnZN

Explain about Promises in js and write the Promise polyfill


Ans:- This is my solution which I coded later https://lnkd.in/giD7TUbM ( can be
error prone please feel free to enrich it)

Explain about setTimeout and how it works?


Ans:- Pretty basic question (refer to Akshay Saini's video)

What is compose function , its polyfill and minor tweaks to make it more generic.
Ans:-
Refer here https://lnkd.in/g8vjMJCq

What is currying and a coding question related to currying


Ans:-
Currying : Refer Akshay Saini 's video on currying (https://lnkd.in/g9kjgeQd)
Coding question and my solution: https://lnkd.in/g7TUp5Nz
Few trick questions based on vanilla js where core basics of vanilla js is required
Don't remember the exact question but similar questions can be found here
https://lnkd.in/ge5HZcDD

Deep dive into #react fiber


Couldnt answer it because it was new for me .
Answer : https://lnkd.in/ggimT68q

what is #redux and how it works


Answered it very well
Answer : https://redux.js.org/

Advanced questions on #git


Had trouble here
Answer : https://lnkd.in/gxiufpa6

Question on how to improve web performace


Answered partially
Answer : https://lnkd.in/gxxu4Jz8

Question on js event loop and browser objects


Answered it well
Answer : Refer Namaste Javascript video series

:- Coding question
Design custom JSON . parse method which takes a string and return json.
Couldn't solve it

https://developer.mozilla.org/en-US/docs/Learn/Performance/What_is_web_performance
https://www.digitalocean.com/community/questions/how-do-i-pass-client-ip-in-a-
kubernetes-cluster-to-my-nodejs-application

Ques: Given a multidimensional array with depth of n, flatten it. Once flattened
make it available as a method on array instance

Solution
/**
* [1,2,[3,4]] -> [1,2,3,4]
*/

let arr = [1,2,[3,4, [5,6, [7, [8, 9, 10]]]]]

function flatten(arr) {
return arr.reduce(function(acc, next){
let isArray = Array.isArray(next)
return acc.concat(isArray ? flatten(next) : next)
}, [])
}

if (!Array.prototype.flatten) {
Array.prototype.flatten = function() {
return flatten(this)
}
}
console.log(arr.flatten());
Ques: Create a promise from scratch

Solution
class CustomPromise {
state = "PENDING"
value = undefined
thenCallbacks = []
errorCallbacks = []

constructor(action) {
action(this.resolver.bind(this), this.reject.bind(this))
}

resolver(value) {
this.state = "RESOLVED"
this.value = value
this.thenCallbacks.forEach((callback) => {
callback(this.value)
})
}

reject(value) {
this.state = "REJECTED"
this.value = value
this.errorCallbacks.forEach((callback) => {
callback(this.value)
})
}

then(callback) {
this.thenCallbacks.push(callback)
return this
}

catch (callback) {
this.errorCallbacks.push(callback)
return this
}
}

let promise = new CustomPromise((resolver, reject) => {


setTimeout(() => {
const rand = Math.ceil(Math.random(1 * 1 + 6) * 6)
if (rand > 2) {
resolver("Success")
} else {
reject("Error")
}
}, 1000)
})

promise
.then(function(response){
console.log(response)
})
.catch(function(error){
console.log(error)
})
Ques: Filter movie list by average rating, name. Sort filtered list by any field
inside movie object
Ans:// O(M)
function getMovies() {
return []; // [{id, name, year}]
}

// O(R)
function getRatings() {
return []; // [{id, movie_id, rating}] 0 <= rating <= 10 // e.g 9.3
}

/**
* minAvgRating ->
* avgRating >= minAvgRating
*
* sort ->
* name -> ascending order movies by name
* -name -> descending
*
* avgRating
*
*
* search ->
* 'ave' -> 'Avengers'
* 'avengers' -> 'Avengers'
* 'AvengersInfinitywar' -> 'Avengers'
*/
const toLower = str => str.toLocaleLowerCase()

const getAvrgRating = (movie, movingWithRatings) => {


let count = 0;
return movingWithRatings.reduce((acc, value, index) => {
const movieMatch = movie.id === value.movie_id
if (movieMatch) {
acc+=value.rating
count++
}
if (index === movingWithRatings.length - 1) {
acc = acc/count
}
return acc
}, 0)
}

const isSubString = (str1, str2) => {


str1 = toLower(str1.split(" ").join(""))
str2 = toLower(str2.split(" ").join(""))
if (str1.length > str2.length) {
return str1.startWith(str2)
} else {
return str2.startWith(str1)
}
}

const moviesList = getMovies()


const movingWithRatings = getRatings();
function queryMovies({ search, sort, minAvgRating }) {
let filteredMovies = movingWithRatings.filter(movie => getAvrgRating(movie,
movingWithRatings) >= minAvgRating);
filteredMovies = filteredMovies.map(movie => moviesList.filter(listItem =>
listItem.id === movie.movie_id).pop())
filteredMovies = filteredMovies.filter(movie => isSubString(toLower(movie.name),
toLower(search)))
filteredMovies = filteredMovies.sort((a, b) => {
const isDescending = sort[0] === '-' ? true : false
let sortCopy = isDescending ? sort.slice(1) : sort
const value1 = a[sortCopy]
const value2 = b[sortCopy]
if (isDescending) {
return value1 > value2 ? -1 : 1
}else {
return value1 < value2 ? -1 : 1
}
})
filteredMovies = filteredMovies.map(movie => ({
...movie,
avgRating: movingWithRatings.filter(ratedMovie => ratedMovie.movie_id ===
movie.id)[0].rating
}))
return filteredMovies
}

Ques: Given an end point URL to fetch all the posts and comments. Do the following.

Map all the comments to the posts it belongs to. The resultant data after mapping
should be of below structure.
{
postId: [commentId, commentId]
}
Ans:
//service.js
const POSTS_URL = `https://jsonplaceholder.typicode.com/posts`;
const COMMENTS_URL = `https://jsonplaceholder.typicode.com/comments`;

export const fetchAllPosts = () => {


return fetch(POSTS_URL).then(res => res.json());
};

export const fetchAllComments = () => {


return fetch(COMMENTS_URL).then(res => res.json());
};

import { fetchAllPosts, fetchAllComments } from "./service";

const fetchData = async () => {


const [posts, comments] = await Promise.all([
fetchAllPosts(),
fetchAllComments()
]);

const grabAllCommentsForPost = postId =>


comments.filter(comment => comment.postId === postId);

const mappedPostWithComment = posts.reduce((acc, post) => {


const allComments = grabAllCommentsForPost(post.id);
acc[post.id] = allComments;
return acc;
}, {});

console.log("mappedPostWithComment ", mappedPostWithComment);


};

fetchData();

Ques:Implement a method getHashCode on string instance. The method should be


available on all strings.
Solution:
let s1 = "sample"

if (!String.prototype.getHashCode) {
String.prototype.getHashCode = function(){
console.log('String instance ', this)
return this
}
}

Ques:What does the below expressions evaluate to


1+true
true+true
‘1’+true
‘2’ > ’3’
‘two’>’three’
Ans:
2
2
1true
false
true

Ques:Implement bind and reduce.


Solution:
//bind
if (!Function.prototype.bind) {
Function.prototype.bind = function(...arg){
const func = this
const context = arg[0]
const params = arg.slice(1)
return function(...innerParam) {
func.apply(context, [...params, ...innerParam])
}
}
}

//reduce
Array.prototype.reduce = function(func, initState) {
const arr = this
const callback = func
let init = initState
arr.forEach(function(value, index){
init=callback(init, value)
})
return init
}

Ques:Implement debounce function


Solution
const debounce = function(func, interval) {
let timerId;
return function(e){
clearTimeout(timerId)
timerId = setTimeout(function(){
func.apply()
}, interval)
}
}
debounce(apiCall, 3000)

Ques:Implement throttling function


Solution:
const throttle = (callback, interval) => {
let timerId;
let allowEvents = true;
return function() {
let context = this;
let args = arguments;

if (allowEvents) {
callback.apply(context, args)
allowEvents = false;
timerId = setTimeOut(function(){
allowEvents = true
}, interval)
}
}
}

Ques: Design API polling mechanism. The API is called after a fixed interval. The
API is a stock API that fetches the latest price of stock. Upon fetching the
results, render the UI.
The question demands the design aspect of the solution and not the code. It was
open ended question.
Solution
//With setInterval, throttling and flags
setInterval=>Endpoint=>Render

//with the inversion of control


//Endpoint=>Render=>setTimeout=>Endpoint=>Render=>SetTimeout...

Ques:Convert class based inheritance code given below to ES5 code.


class Parent(name){
constructor(name) {
this.name=name
}
getName(){return this.name}
}

class Children extends Parent {


constructor(props){
super(props)
}
}
Solution
function Parent(name) {
this.name = name
}

Parent.prototype.getName = function() {
return this.name
}

function Children(name){
Parent.call(this, name)
}

Children.prototype = new Parent()

Ques:What does following code evaluates to?


//Q.1
var x = 1;
var y = x;

x = 0;
console.log(x, y);

//Q.2
var x = [1];
var y = x;

x = [];
console.log(x,y);

//Q.3
function Abc() { console.log(this); };
Abc()
new Abc();

//Q.4
var x = 1;
var obj = {
x: 2,
getX: function () {
return console.log(this.x);
}
};

obj.getX()
let a = obj.getX
console.log(a)

//Q.5
//How to get the a to log 2 in the above code

//Q.6
console.log("A");
setTimeout(() => console.log("B"), 0);
setTimeout(() => console.log("C"), 0);
console.log("D");

//Q.7
setTimeout(function() {
console.log("A");
}, 0);
Promise.resolve().then(function() {
console.log("B");
}).then(function() {
console.log("C");
});

console.log("D");

//Q.8
let obj1 = {
a:1,
b:2
}

function mutate(obj) {
obj = {a:4, c:6}
}

console.log(obj1)
mutate(obj1)
console.log(obj1)
Solution
//A.1
0 1

//A.2
[] [1]

//A.3
window object is logged

//A.4
logs 2 and 1

//A.5
a.call(obj);

//A.6
A, D, B , C

//A.7
D, B, C, A

//A.8
{ a: 1, b: 2 }
{ a: 1, b: 2 }
Ques:Given an array of numbers implement the following
const list = [1,2,3,4,5,6,7,8]
const filteredArray = list.filter(between(3, 6)) // [4,5]
Solution
function between(start, end) {
return function (value,index) {
return value>start && value<end
}
}

https://dev.to/devabhijeet/all-front-end-interview-questions-asked-during-my-
recent-job-hunt-1kge
https://github.com/devAbhijeet/job-hunt-interview-questions-2020

You might also like