Javascript Interview Prepration
What is Javascript
javascript is scripting or programming language that allow add to complex feature in web page such as dynamically updating content, controlling multimedia, animated images.
Data Types in Javascript
There are 2 kind of data type in js
1) Primitive
Number
String
Boolean
Undefined
Null
2) Object
in javascript except primitive data type everything object type
Array
Function
Object
Function
in javscript function encapsulate js code into reusable blocks
Types of function
Higher Order Function
it's the function which accept function as parameter and return a fuinction as result
const hocFn = (fn1) => {
return fn1()
}
const fn1 = () => {
console.log('hello saurabh')
}
hocFn(fn1)
First Class Function
The function which are treated as variable is called First Class Function
const fn = function() {
console.log('this is first class function')
}
IIFE(Immediately Invoked Function Expression)
it's a function which is called as soon as it's defined
(()=> {
console.log('This is IIFE)
})()
CallBack
It's a function which is passed as parameter to another function and excuted after and event or operation completed. it's widely used to handle asynchronous operation in js such as network request.
function fetchedData(cb) {
setTimeout(() => {
cb('sample call back data')
}, 1000)
}
fetchedData((data) => {
console.log(data)
})
Arrow Functions
it's shorter way of declaring function it has some other advantage as well
if there is only one expression it's implicitly return
const sum = () => a + b
It doesn't have own this context it get's it from parent scope where it's defined
Hoisiting
In javascript variable and function statement allocated memory before executing code this is called hoisting.
Functions gtes memory inside a heap and refrence available in execution context
Ex
real()
function real() {
console.log('I am real always run me')
}
function real() {
console.log('No I am real')
}
function real() {
console.log('You both are wasted')
}
real();
// output
// You both are wasted
// You both are wasted
here all 3 will get meory in heap but real refres to last one so output will be "You both are wasted"
Lexical Scope
it's an ability of a function of accessing varaiable from it's parental scope
//lexical scope
// in js function variables are lexically scoped it means it can find outside the function defination
console.log('line no 1', varName); // undefined
var varName = 10;
function b() {
console.log('at line no 10', varName);
}
function fn() {
console.log('at line no 5', varName); // undefined
var varName = 20;
// suppose there is function where varName not defined
b() // 10
console.log('at line no 7', varName) // 20
}
fn();
Closure
an inner function always have access of variable of outer functions even after executing outer function this concept is called closure
function outer() {
let count = 0;
function inner() {
return count++
}
return inner;
}
const a = outer()
console.log(a())
console.log(a())
console.log(a())
console.log(a())
TDZ(Temporal Dead Zone)
unlike var keyword const and let can't access before declaration they have TDZ.
temporal dead zone is area from where js file starts and till where variable is decalred
console.log(a);
//TDZ
let a = 10
This Keyword in JS
This keyword in js is context refrence which depends on the scope and the manner how ithe function is called
1) Global Context
In Global Execution Context outside any function this refers to global object or window object
console.log(this)
2) Function Context
in strict mode it's undefined untill not set by call but for non strict mode it's global object
function show() {
console.log(this)
// strict mode undefined
// non strict mode global object
}
3) Arrow Functions
Arrow functions doesn't have there own this binding it inherit from the parent scope at the time of defining. it resolve the issue of explicit binding in react
function myFunction() {
return () => {
console.log(this);
};
}
const obj = new myFunction();
obj();
Call, Bind, Apply
These are keywords which allow us assignment of this keyword and pass parameter to function in different ways
Call
it simply invoke the function after setting this value in call we pass parameters as list
function greet(greet) {
console.log(`${greet} ${this.name}`)
}
const obj1 = {
name: 'Saurabh'
}
const obj2 = {
name: 'Rahul'
}
greet.call(obj1, 'hello')
greet.call(obj1, 'welcome')
Apply
it is simlar to call only difference is argument passed as Array
function greet(greet) {
console.log(`${greet} ${this.name}`)
}
const obj1 = {
name: 'Saurabh'
}
const obj2 = {
name: 'Rahul'
}
greet.apply(obj1, ['hello'])
greet.apply(obj1, ['welcome'])
Bind
it return a function with specific this value which can be used later. so it's useful for event handling
function greet(greet) {
console.log(`${greet} ${this.name}`)
}
const obj1 = {
name: 'Saurabh'
}
const show = greet.bind(obj1);
show('welcome')
Polyfill
Polyfill is js piece of code that provide functionality which expected by natively supported browser
Polyfille for map
Array.prototype.myMap = function(cb) {
let arr = [];
for(let i = 0; i < this.length; i++) {
arr.push(cb(this[i], i, this))
}
return arr
}
Polyfill for filter
Array.prototype.myFilter = function(cb) {
let arr = []
for(let i = 0; i < this.length; i++) {
if(cb(this[i], i, this)) {
arr.push(this[i])
}
}
return arr
}
Polyfill for ForEach
Array.prototype.myForEach = function(callback){
for (var i = 0; i < this.length; i++) {
callback(this[i], i, this);
}
}
Polyfill for reduce
Array.prototype.myReduce = function(cb, initialValue) {
let accumlatedValue = initialValue;
for(let i = 0 ; i < this.length; i++) {
if(!!accumlatedValue) {
accumlatedValue = cb(this[i], accumlatedValue, i, this)
}
else {
accumlatedValue = this[i]
}
}
return accumlatedValue;
}
Prototype Inheritence
it's an js core concept which tells how objects and functions intract with each other.every object has prototype property whch is used for following
updating existing property
adding new property
inherting property of another object
after es6 js introduce class and extends keyword which is used for inheritence but internally it uses prototype
Promise
Promise are representation of eventual completion or failure of asynchronus operation and it's result value. before promise callback function is used which create call back hell for multiple asynchronus operation.
Promise has 3 state
Pending - it's initial State
Completed - when operation successfully completed
Rejected - When operation failed due to any reason
const p1 = new Promise((resolve, reject) => {
if(false) {
resolve(10)
}
else {
reject('error')
}
})
p1.then(data => {
console.log(data)
})
.catch(error => {
console.log(error)
})
Promise.all
when there are multiple promise which are not dependent on each other we want to execute something after completing all result we use promise.all it resolved if all promise success otherwise reject it.
const p1 = new Promise((resolve, reject) => {
if(true) {
resolve(10)
}
else {
reject('error')
}
})
const p2 = new Promise((resolve, reject) => {
if(true) {
resolve(20)
}
else {
reject('error')
}
})
Promise.all([p1, p2]).then(result => {
console.log(result)
}).catch(error => {
console.log(error)
})
Async / Await
it's used write and read asynchronus code in easy way
const p1 = new Promise((resolve, reject) => {
if(true) {
resolve(10)
}
else {
reject('error')
}
})
const p2 = new Promise((resolve, reject) => {
if(true) {
resolve(20)
}
else {
reject('error')
}
})
const displayPromiseResult = async () => {
try {
const allPromise = await Promise.all([p1, p2]);
console.log(allPromise)
}
catch(error) {
console.log(error)
}
}
displayPromiseResult()
Let, Var and Const
var
Scope - The var keyword has functional and global scope.
redeclare - we can redeclare the variable by using the var keyword.
reassign - we can reassign values to the variable that are declared with the var keyword.
TDZ(Temporal Dead Zone) - There is no TDZ for the variable that is declared with the var keyword.
let
Scope - The let keyword has a block scope.
redeclare - we can't redeclare the variable by using the let keyword.
reassign - we can reassign values to the variables that are declared with the let keyword.
TDZ(Temporal Dead Zone) - TDZ is available for the variables declared with the let keyword.
const
it's used to declare constant values.
Scope - The const keyword has a block scope.
redeclare - we can't redeclare the variable by using the let keyword.
reassign - we can't reassign values to the variables that are declared with the const keyword.
SetTimeout vs SetInterval
setTimeout(function() {
console.log("This message is shown after 3 seconds");
}, 3000);
it execute the code after specified delay
setInterval(function() {
console.log("This message is shown every 2 seconds");
}, 2000);
it repeatedly execute same function in regular interval
Spread Operator
it's used to copy objects data
it's used concate objects
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const combinedObj = { ...obj1, ...obj2 }; // { a: 1, b: 3, c: 4 }
RestParameter
it's syntax similar to spread operator but it allow function expect indefinite arguments as an array
function sum(...numbers) {
return numbers.reduce((acc, current) => acc + current, 0);
}
console.log(sum(1, 2, 3, 4)); // Outputs: 10
Shallow Copy
it just copy top level structure not nested objects
const obj = {
name: 'saurabh'
address: {
add1: 'some address'
}
}
const obj2 = {...obj}
const obj3 = Object.assign({}, obj)
// reference for address doesn't change
Deep Copy
it create new instance of the object or array by copying all the data but it has some limitation also it doesn't change reference for undefined, methods so for that we have structured clone for deep copy.
const obj = {
name: 'saurabh'
address: {
add1: 'some address'
}
}
const obj2 = JSON.parse(JSON.stringify(obj));
Event Delegation
it's a technique in which instead of adding event at each individual add events to there parent.
<ul id="myList">
<li>First</li>
<li>First</li>
<li>First</li>
</ul>
document.getElementById('myList').addEventListener('click', function(event) {
// Check if the clicked element is a list item
if (event.target && event.target.nodeName === 'LI') {
console.log('List item ', event.target.textContent, ' was clicked!');
}
});
// This will work even for list items added later to the myList element
Event Propogation
It's a mechanism that tells how event propogate or travel through DOM(Document object model). It has 3 phases
1 Capturing - it goes from document object to target element
2 Target - trigger on target element
3 Bubbling - after reaching target element if bubbling is enabled it reverse back to top in dom tree till document object
Event Capturing
<div id="parentDiv">
<div id="childDiv">Child Text</div>
</div>
document.getElementById('parentDiv').addEventListener('click',() => {
alert('parent called',)
}, true)
document.getElementById('childDiv').addEventListener('click',() => {
alert('child called',)
})
Event Bubbling
document.getElementById('parentDiv').addEventListener('click',() => {
alert('parent called')
})
document.getElementById('childDiv').addEventListener('click',() => {
alert('child called')
})
Throttling vs Debouncing
Throttling
it's a technique in which it doesn't matter how many times user fires a event it will excuted only once in a given time interval. loadsh library used for this
ex. used for scrolling
Debouncing
it's a technique in which attached callback is excuted after the specified time when user stops firing event.
ex. used for search data component
Object.seal vs Object.freeze
Object.seal()
When an object is sealed with Object.seal()
:
Prevents Adding New Properties: You cannot add new properties to the sealed object.
Prevents Deleting Existing Properties: You cannot remove existing properties from the sealed object.
Allows Modification of Existing Properties: However, it still allows you to modify the values of existing properties (as long as they are writable).
const sealedObject = { prop: 1 };
Object.seal(sealedObject);
sealedObject.prop = 2; // Allowed
sealedObject.newProp = 3; // Not allowed, newProp will not be added
delete sealedObject.prop; // Not allowed, prop will not be deleted
Object.freeze()
Object.freeze()
is more restrictive than Object.seal()
:
Prevents Adding New Properties: You cannot add new properties to the frozen object.
Prevents Deleting Existing Properties: You cannot remove existing properties.
Prevents Modifying Existing Properties: It also prevents modifying the existing property values. This means that the object is made completely immutable (assuming its existing properties are primitive values or immutable themselves).
const frozenObject = { prop: 1 };
Object.freeze(frozenObject);
frozenObject.prop = 2; // Not allowed, prop will remain 1
frozenObject.newProp = 3; // Not allowed, newProp will not be added
delete frozenObject.prop; // Not allowed, prop will not be deleted
Set
// Creating a set
let mySet = new Set();
// Adding elements to the set
mySet.add(1);
mySet.add(2);
mySet.add(3);
mySet.add(2); // Duplicate entry, will be ignored
// Checking the size of the set
console.log(mySet.size); // Output: 3
// Checking if an element exists in the set
console.log(mySet.has(2)); // Output: true
// Deleting an element from the set
mySet.delete(2);
// Iterating over the set
mySet.forEach((value) => {
console.log(value);
});
Map
A Map is a collection of key-value pairs where each key is unique. It's similar to an object but with more flexibility and additional methods for manipulation.
// Creating a map
let myMap = new Map();
// Adding key-value pairs to the map
myMap.set('key1', 'value1');
myMap.set('key2', 'value2');
myMap.set('key3', 'value3');
// Getting the value associated with a key
console.log(myMap.get('key2')); // Output: value2
// Checking if a key exists in the map
console.log(myMap.has('key2')); // Output: true
// Deleting a key-value pair from the map
myMap.delete('key2');
// Iterating over the map
myMap.forEach((value, key) => {
console.log(`${key} => ${value}`);
});
Generator Function
In JavaScript, a generator function is a special type of function that can be paused and resumed during its execution. It's defined using the function*
syntax and yields values using the yield
keyword. When a generator function is called, it returns a generator object, which can then be used to control the execution of the function
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
// Creating a generator object
const gen = myGenerator();
// Calling next() on the generator object returns an object with the value yielded by the generator
console.log(gen.next()); // Output: { value: 1, done: false }
console.log(gen.next()); // Output: { value: 2, done: false }
console.log(gen.next()); // Output: { value: 3, done: false }
console.log(gen.next()); // Output: { value: undefined, done: true }