Click ⭐if you like the project and follow LinkedIn Profile for more updates. Check API Collection Free
JavaScript is a versatile programming language primarily used for enhancing web pages to provide interactive content, such as forms, animations, and dynamic user experiences. It runs in the browser and is often used for both client-side and server-side scripting.
JavaScript supports several data types, including:
- Primitive types:
string
,number
,boolean
,null
,undefined
,symbol
, andbigint
. - Non-primitive types:
object
, includingArray
,Function
, andDate
.
The difference between let
, const
, and var
is related to scope and reassignment:
var
is function-scoped, can be redeclared, and is hoisted to the top.let
is block-scoped, can't be redeclared but can be reassigned.const
is block-scoped, can't be redeclared or reassigned (though objects and arrays can still have their contents modified).
Example:
var x = 1;
let y = 2;
const z = 3;
==
: Checks for equality after type coercion. It converts the operands to the same type before making the comparison.===
: Checks for strict equality, meaning both value and type must be the same.
Example:
console.log(1 == '1'); // true (type coercion)
console.log(1 === '1'); // false (strict equality)
A closure is a function that remembers and has access to variables from its outer scope, even after the outer function has finished executing.
Example:
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
console.log(outerVariable, innerVariable);
};
}
const newFunction = outerFunction('outside');
newFunction('inside'); // outside inside
Hoisting is a JavaScript mechanism where variable and function declarations are moved to the top of their scope before code execution. Only declarations are hoisted, not initializations.
Example:
console.log(a); // undefined
var a = 5;
hoistedFunction(); // "Hoisted!"
function hoistedFunction() {
console.log("Hoisted!");
}
The value of this in JavaScript refers to the context in which a function is invoked. It can change depending on how a function is called, such as within a method, globally, or via call, apply, or bind.
Example:
const obj = {
name: 'Alice',
greet() {
console.log(`Hello, ${this.name}`);
}
};
obj.greet(); // "Hello, Alice"
A prototype is an object from which other objects inherit properties and methods. Every JavaScript object has a prototype, which allows for inheritance.
Example:
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hello, my name is ${this.name}`);
};
const alice = new Person('Alice');
alice.greet(); // Hello, my name is Alice
null: Represents an intentional absence of any object value. It must be assigned explicitly. undefined: Represents a variable that has been declared but not yet assigned a value.
Example:
let a; // a is undefined
let b = null; // b is explicitly set to null
JavaScript handles asynchronous operations using callback functions, promises, and async/await. These allow non-blocking operations, such as fetching data from an API or reading a file.
Example using a promise:
fetch('https://api.example.com')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
A promise is an object representing the eventual completion or failure of an asynchronous operation. It has three states: pending, fulfilled, and rejected.
Example:
let promise = new Promise((resolve, reject) => {
// Asynchronous operation
setTimeout(() => {
resolve("Data received");
}, 1000);
});
promise.then(data => console.log(data)); // Logs: Data received
async and await are syntactic sugars for working with promises. An async function always returns a promise, and await pauses the execution until the promise is resolved.
Example:
async function fetchData() {
let data = await new Promise((resolve) => {
setTimeout(() => resolve("Data received"), 1000);
});
console.log(data);
}
fetchData(); // Logs: Data received
Event delegation involves attaching a single event listener to a parent element to manage events for its children. This approach leverages event bubbling to handle events for multiple child elements.
Example:
document.querySelector("#parent").addEventListener("click", function (event) {
if (event.target && event.target.matches("button")) {
console.log("Button clicked:", event.target.textContent);
}
});
JavaScript modules allow you to split code into separate files, each with its own scope. Modules use export and import to share and use code.
Example:
math.js:
export function add(x, y) {
return x + y;
}
main.js:
import { add } from "./math.js";
console.log(add(2, 3)); // Logs: 5
Techniques include using flags, debouncing, and throttling.
Example:
let isCalled = false;
function myFunction() {
if (!isCalled) {
isCalled = true;
// Function logic here
}
}
The event loop is a mechanism that allows JavaScript to handle asynchronous operations by continuously checking the call stack and message queue.
Both methods invoke a function with a specified this value. call() accepts arguments individually, while apply() accepts arguments as an array.
Example:
function greet(greeting, name) {
console.log(`${greeting}, ${name}!`);
}
greet.call(null, "Hello", "John"); // Hello, John!
greet.apply(null, ["Hello", "John"]); // Hello, John!
bind() creates a new function with a specified this value and initial arguments.
Example:
function greet(greeting, name) {
console.log(`${greeting}, ${name}!`);
}
let greetHello = greet.bind(null, "Hello");
greetHello("John"); // Hello, John!
The event loop is the mechanism that allows JavaScript to perform non-blocking operations by handling asynchronous tasks and ensuring that the code executes in a single thread.
Event Bubbling: The event starts from the target element and bubbles up to the root. Event Capturing: The event starts from the root and captures down to the target element.
Example:
document.querySelector("#child").addEventListener(
"click",
function (event) {
console.log("Child clicked");
},
true
); // true for capturing
document.querySelector("#parent").addEventListener("click", function (event) {
console.log("Parent clicked");
});
Shallow Copy: Copies only the top-level properties. Nested objects are shared between the original and copied objects.
Deep Copy: Copies all levels of properties, creating independent nested objects.
Example:
let original = { a: 1, b: { c: 2 } };
let shallowCopy = { ...original };
let deepCopy = JSON.parse(JSON.stringify(original));
shallowCopy.b.c = 3;
console.log(original.b.c); // 3 (shallow copy shares nested object)
console.log(deepCopy.b.c); // 2 (deep copy does not affect original)
Generator functions use the function* syntax and return an iterator. They allow pausing and resuming execution, and yield values one at a time.
Example:
function* generator() {
yield 1;
yield 2;
yield 3;
}
let gen = generator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
The new keyword creates an instance of a constructor function or class.
Example:
function Person(name) {
this.name = name;
}
let person = new Person("John");
console.log(person.name); // John
setTimeout(fn, delay): Executes fn once after delay milliseconds. setInterval(fn, interval): Executes fn repeatedly every interval milliseconds.
Example:
setTimeout(() => console.log("Executed once"), 1000);
setInterval(() => console.log("Executed repeatedly"), 1000);
WeakMap is a collection of key-value pairs where keys are objects and are held weakly (i.e., if no other references to the key exist, the entry is garbage collected). Map holds keys and values strongly.
Example:
let weakMap = new WeakMap();
let obj = {};
weakMap.set(obj, "value");
console.log(weakMap.get(obj)); // value
A Set is a collection of unique values. It allows you to store and manage unique elements.
Example:
let set = new Set([1, 2, 2, 3]);
console.log(set.has(2)); // true
console.log(set.size); // 3
Object.create() creates a new object with the specified prototype object and properties.
Example:
let proto = {
greet() {
console.log("Hello");
},
};
let obj = Object.create(proto);
obj.greet(); // Hello
JavaScript uses automatic garbage collection to manage memory. It identifies and frees memory that is no longer in use or reachable by the application.
Decorators are a proposal for adding metadata and modifying classes and properties. They provide a way to annotate and modify class declarations and methods.
Example:
function readonly(target, key, descriptor) {
descriptor.writable = false;
return descriptor;
}
class Example {
@readonly
name() {
return "Name";
}
}
prototype: An object associated with a constructor function, used for inheritance. proto: An internal property that refers to the prototype of the object's constructor.
Example:
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function () {
console.log("Hi");
};
let john = new Person("John");
console.log(john.__proto__ === Person.prototype); // true
Object.assign() copies the values of all enumerable properties from one or more source objects to a target object.
Example:
let target = { a: 1 };
let source = { b: 2 };
Object.assign(target, source);
console.log(target); // { a: 1, b: 2 }
Template literals are string literals allowing embedded expressions, multi-line strings, and interpolation.
Example:
let name = "John";
let greeting = `Hello, ${name}!`;
console.log(greeting); // Hello, John!
The spread operator (...) allows an iterable (e.g., array) to be expanded into individual elements.
Example:
let arr = [1, 2, 3];
let newArr = [...arr, 4, 5];
console.log(newArr); // [1, 2,
The rest parameter (...) allows a function to accept an indefinite number of arguments as an array.
Example:
function sum(...numbers) {
return numbers.reduce((acc, num) => acc + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
The for...of loop iterates over iterable objects (e.g., arrays, strings) and returns the values of the items.
Example:
let arr = [1, 2, 3];
for (let value of arr) {
console.log(value);
}
// Logs: 1, 2, 3
async and await are used to work with promises more comfortably. async defines a function that returns a promise, and await pauses execution until the promise resolves.
Example:
async function fetchData() {
let data = await new Promise((resolve) => {
setTimeout(() => resolve("Data received"), 1000);
});
console.log(data);
}
fetchData(); // Logs: Data received
Symbol is a primitive data type used to create unique identifiers for object properties. It ensures that property keys are unique and not susceptible to accidental overwrites.
Example:
const uniqueKey = Symbol("key");
let obj = { [uniqueKey]: "value" };
console.log(obj[uniqueKey]); // value
Classes are created using the class keyword and can include a constructor and methods.
Example:
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, ${this.name}`);
}
}
let john = new Person("John");
john.greet(); // Hello, John
Destructuring allows unpacking values from arrays or properties from objects into distinct variables.
Example:
Array Destructuring:
let [a, b] = [1, 2];
console.log(a, b); // 1 2
Object Destructuring:
let { x, y } = { x: 1, y: 2 };
console.log(x, y); // 1 2
The Proxy object enables creation of a handler object that can intercept and redefine fundamental operations for another object (e.g., property access, assignment).
Example:
let target = {};
let handler = {
get: function (target, prop, receiver) {
return prop in target ? target[prop] : "default";
},
};
let proxy = new Proxy(target, handler);
console.log(proxy.someProperty); // default
Example:
function findLongestWord(sentence) {
let words = sentence.split(' ');
let longestWord = words.reduce((longest, current) => current.length > longest.length ? current : longest, '');
return longestWord;
}
console.log(findLongestWord("The quick brown fox jumps over the lazy dog"));
Example:
function isPalindrome(str) {
let cleaned = str.replace(/[^A-Za-z0-9]/g, "").toLowerCase();
let reversed = cleaned.split("").reverse().join("");
return cleaned === reversed;
}
console.log(isPalindrome("A man, a plan, a canal, Panama")); // true
Example:
function removeDuplicates(arr) {
return [...new Set(arr)];
}
console.log(removeDuplicates([1, 2, 2, 3, 4, 4, 5])); // [1, 2, 3, 4, 5]
Example:
function reverseString(str) {
let reversed = "";
for (let i = str.length - 1; i >= 0; i--) {
reversed += str[i];
}
return reversed;
}
console.log(reverseString("hello")); // "olleh"
Example:
function maxConsecutiveOnes(arr) {
let maxCount = 0;
let currentCount = 0;
for (let num of arr) {
if (num === 1) {
currentCount++;
maxCount = Math.max(maxCount, currentCount);
} else {
currentCount = 0;
}
}
return maxCount;
}
console.log(maxConsecutiveOnes([1, 1, 0, 1, 1, 1, 0, 1])); // 3
Example:
function factorial(n) {
if (n === 0) return 1;
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120
Example:
function mergeAndSort(arr1, arr2) {
return [...arr1, ...arr2].sort((a, b) => a - b);
}
console.log(mergeAndSort([0, 3, 4, 31], [4, 6, 30])); // [0, 3, 4, 4, 6, 30, 31]
Example:
function checkSquared(arr1, arr2) {
if (arr1.length !== arr2.length) return false;
let freq1 = {};
let freq2 = {};
arr1.forEach((num) => (freq1[num] = (freq1[num] || 0) + 1));
arr2.forEach((num) => (freq2[num] = (freq2[num] || 0) + 1));
return Object.keys(freq1).every((key) => freq2[key ** 2] === freq1[key]);
}
console.log(checkSquared([1, 2, 3], [1, 4, 9])); // true
49. Given two strings, find if one string can be formed by rearranging the letters of the other string
Example:
function canForm(str1, str2) {
if (str1.length !== str2.length) return false;
let sortedStr1 = str1.split("").sort().join("");
let sortedStr2 = str2.split("").sort().join("");
return sortedStr1 === sortedStr2;
}
console.log(canForm("listen", "silent")); // true
Example:
function getUniqueObjects(arr) {
let seen = new Set();
return arr.filter((obj) => {
let key = JSON.stringify(obj);
if (!seen.has(key)) {
seen.add(key);
return true;
}
return false;
});
}
console.log(
getUniqueObjects([
{ name: "sai" },
{ name: "Nang" },
{ name: "sai" },
{ name: "Nang" },
{ name: "111111" },
])
);
// [{name: "sai"}, {name: "Nang"}, {name: "111111"}]
Example:
function findMax(arr) {
return Math.max(...arr);
}
console.log(findMax([1, 2, 3, 4, 5])); // 5
52. Write a JavaScript function that takes an array of numbers and returns a new array with only the even numbers
Example:
function filterEvenNumbers(arr) {
return arr.filter((num) => num % 2 === 0);
}
console.log(filterEvenNumbers([1, 2, 3, 4, 5])); // [2, 4]
Example:
function isPrime(num) {
if (num <= 1) return false;
for (let i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) return false;
}
return true;
}
console.log(isPrime(7)); // true
Example:
function findLargestInNestedArray(arr) {
let flattenArray = arr.flat(Infinity);
return Math.max(...flattenArray);
}
console.log(
findLargestInNestedArray([
[3, 4, 58],
[709, 8, 9, [10, 11]],
[111, 2],
])
); // 709
Example:
function fibonacci(n) {
let sequence = [0, 1];
while (sequence.length < n) {
let nextTerm =
sequence[sequence.length - 1] + sequence[sequence.length - 2];
sequence.push(nextTerm);
}
return sequence;
}
console.log(fibonacci(5)); // [0, 1, 1, 2, 3]
56. Given a string, write a JavaScript function to count the occurrences of each character in the string
Example:
function countOccurrences(str) {
let occurrences = {};
for (let char of str) {
occurrences[char] = (occurrences[char] || 0) + 1;
}
return occurrences;
}
console.log(countOccurrences("hello")); // {h: 1, e: 1, l: 2, o: 1}
Example:
function sortAscending(arr) {
return arr.sort((a, b) => a - b);
}
console.log(sortAscending([5, 3, 8, 1, 2])); // [1, 2, 3, 5, 8]
Example:
function sortDescending(arr) {
return arr.sort((a, b) => b - a);
}
console.log(sortDescending([5, 3, 8, 1, 2])); // [8, 5, 3, 2, 1]
59. Write a JavaScript function that reverses the order of words in a sentence without using the built-in reverse() method
Example:
function reverseWords(sentence) {
let words = sentence.split(" ");
let reversedSentence = "";
for (let i = words.length - 1; i >= 0; i--) {
reversedSentence += words[i] + " ";
}
return reversedSentence.trim();
}
console.log(reverseWords("Hello world")); // "world Hello"
Example:
function flattenArray(arr) {
return arr.flat(Infinity);
}
console.log(flattenArray([[1, 2, [3]], [4, [5, [6]]]])); // [1, 2, 3, 4, 5, 6]
React is a JavaScript library for building user interfaces, specifically for single-page applications. It allows developers to create reusable UI components.
Example:
import React from "react";
function App() {
return <h1>Hello, World!</h1>;
}
export default App;
useMemo is a React hook that memoizes the result of a computation to avoid expensive recalculations on every render unless its dependencies change.
Example:
import React, { useMemo } from "react";
function Example({ number }) {
const computedValue = useMemo(() => {
return number * 2;
}, [number]);
return <div>{computedValue}</div>;
}
- Component-based architecture
- Virtual DOM
- One-way data binding
- JSX (JavaScript XML)
Example:
import React from "react";
function Header() {
return <header>This is a header</header>;
}
function App() {
return (
<div>
<Header />
<p>This is the body</p>
</div>
);
}
export default App;
JSX is a syntax extension for JavaScript that allows you to write HTML elements in JavaScript.
Example:
const element = <h1>Hello, World!</h1>;
The DOM (Document Object Model) represents the structure of a web document as a tree of objects.
Example (in the browser):
<!DOCTYPE html>
<html>
<body>
<div id="app"></div>
<script>
document.getElementById("app").innerText = "Hello, World!";
</script>
</body>
</html>
The Virtual DOM is an in-memory representation of the real DOM, used by React to optimize updates by re-rendering only the changed parts of the DOM.
Example:
const element = <h1>Hello, World!</h1>;
ReactDOM.render(element, document.getElementById("root"));
The lifecycle includes:
- Mounting: constructor(), render(), componentDidMount()
- Updating: componentDidUpdate()
- Unmounting: componentWillUnmount()
Example:
class MyComponent extends React.Component {
componentDidMount() {
console.log("Component Mounted");
}
render() {
return <div>Life Cycle</div>;
}
}
Fragments let you group a list of children without adding extra nodes to the DOM.
Example:
import React from "react";
function FragmentExample() {
return (
<>
<h1>Title</h1>
<p>Description</p>
</>
);
}
Props are read-only attributes passed from a parent component to a child component.
Example:
function Greeting(props) {
return <h1>Hello, {props.name}</h1>;
}
Synthetic events are React's cross-browser wrapper around the browser's native events.
Example:
function Button() {
const handleClick = (event) => {
console.log("Button clicked", event);
};
return <button onClick={handleClick}>Click me</button>;
}
- package.json: Lists project dependencies.
- package-lock.json: Records the exact versions of installed dependencies.
- Client-side rendering: The content is rendered in the browser using JavaScript.
- Server-side rendering: Content is rendered on the server and sent as a fully-rendered page.
State is an object that holds dynamic data within a component. When the state changes, the component re-renders.
Example:
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<p>Count: {count}</p>
</div>
);
}
Props are used to pass data from a parent component to a child component.
Example:
function Child(props) {
return <p>{props.message}</p>;
}
function Parent() {
return <Child message="Hello from Parent" />;
}
- State: Local to a component, can be changed.
- Props: Passed from parent to child, read-only.
- Props drilling is the process of passing props down through multiple levels of components, - even if intermediate components don't need the data.
- Disadvantages: Leads to tightly coupled components.
- Solution: Use React Context API or state management libraries like Redux.
Pure components in React are components that perform a shallow comparison of props and state to avoid unnecessary re-renders.
Example:
class MyPureComponent extends React.PureComponent {
render() {
return <div>{this.props.name}</div>;
}
}
Refs provide a way to access the DOM elements or React components directly.
Example:
import React, { useRef } from "react";
function InputComponent() {
const inputRef = useRef();
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}
forwardRef is a technique to pass refs from a parent to a child component.
Example:
const FancyInput = React.forwardRef((props, ref) => <input ref={ref} />);
Error boundaries catch JavaScript errors in child components and display a fallback UI.
Example:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
this.setState({ hasError: true });
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
A Higher Order Component (HOC) is a function that takes a component and returns a new component with added functionality.
Example:
function withLogger(WrappedComponent) {
return function (props) {
console.log("Component rendered");
return <WrappedComponent {...props} />;
};
}
- Controlled components: Form data is handled by React state.
- Uncontrolled components: Form data is handled by the DOM.
useCallback is a hook that memoizes a function to prevent it from being recreated on every render unless its dependencies change.
Example:
import React, { useCallback, useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => setCount(count + 1), [count]);
return <button onClick={increment}>Increment</button>;
}
- useMemo: Memoizes the result of a computation.
- useCallback: Memoizes the function itself.
Keys help React identify which items have changed, been added, or removed.
Example:
const list = ["Apple", "Banana", "Cherry"];
const items = list.map((item, index) => <li key={index}>{item}</li>);
Lazy loading is the technique of loading components or resources only when they are needed.
Example:
const LazyComponent = React.lazy(() => import("./LazyComponent"));
function App() {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</React.Suspense>
);
}
Suspense is a component that allows for delaying the rendering of a component until some condition (like data fetching) is met.
Example:
<React.Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</React.Suspense>
Custom hooks are reusable functions that allow you to share logic between components.
Example:
function useCounter(initialValue = 0) {
const [count, setCount] = React.useState(initialValue);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return { count, increment, decrement };
}
useReducer is a hook that is used to manage more complex state logic compared to useState.
Example:
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
<span>{state.count}</span>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
</>
);
}
Portals allow rendering components outside their parent DOM hierarchy.
Example:
ReactDOM.createPortal(<Child />, document.getElementById("modal-root"));
The Context API allows you to pass data through the component tree without passing props manually at every level.
Example:
const ThemeContext = React.createContext("light");
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return <ThemedButton />;
}
function ThemedButton() {
const theme = React.useContext(ThemeContext);
return <button style={{ background: theme }}>Click me</button>;
}
- See the answer for the Context API example above.
The callback function in setState ensures that state updates are processed before executing further logic.
Example:
this.setState({ count: this.state.count + 1 }, () => {
console.log("State updated!");
});
- See the example in the custom hook question above.
useEffect replaces componentDidMount, componentDidUpdate, and componentWillUnmount.
Example:
useEffect(() => {
console.log("Component mounted");
return () => console.log("Component unmounted");
}, []);
Strict Mode is a tool that highlights potential problems in an application by identifying unsafe lifecycle methods or deprecated APIs.
Example:
<React.StrictMode>
<App />
</React.StrictMode>
- Using a callback function.
- Using useRef.
- Context API.
Example:
function Parent() {
const handleData = (data) => {
console.log(data);
};
return <Child sendData={handleData} />;
}
function Child({ sendData }) {
return (
<button onClick={() => sendData("Hello from Child")}>Send Data</button>
);
}
Example:
function Parent() {
const childRef = React.useRef();
const handleClick = () => {
alert(childRef.current.value);
};
return (
<div>
<Child ref={childRef} />
<button onClick={handleClick}>Get Child Value</button>
</div>
);
}
const Child = React.forwardRef((props, ref) => {
return <input ref={ref} type="text" />;
});