- What are the data types in JavaScript?
- What is the difference between var, let, and const?
- What are primitive and non-primitive data types?
- What is hoisting in JavaScript?
- What is the difference between == and ===?
- Explain scope in JavaScript.
- What is a closure?
- What is a callback function?
- What is the difference between null and undefined?
- What is NaN and how can you check for it?
- What is the difference between function declaration and function expression?
- What is an IIFE (Immediately Invoked Function Expression)?
- What is event bubbling and event capturing?
- What is the difference between synchronous and asynchronous code?
- What is the typeof operator and how does it work?
- What are template literals?
- What is the use of
thiskeyword? - What is the use of bind(), call(), and apply()?
- What are arrow functions and how are they different from regular functions?
- What are truthy and falsy values in JavaScript?
- What is the event loop in JavaScript?
- Explain how
setTimeoutandsetIntervalwork. - What is the difference between shallow copy and deep copy?
- What are JavaScript Promises? How do they work?
- What is async/await and how is it different from Promises?
- What is destructuring in JavaScript?
- What are spread and rest operators?
- What is the difference between
for,for..in, andfor..ofloops? - What are
map,filter, andreducemethods? - How does prototypal inheritance work in JavaScript?
- What is the difference between Object and Map?
- How do you handle errors in JavaScript?
- What is the use of
Object.freeze()andObject.seal()? - What are higher-order functions?
- What is a pure function?
- What is currying in JavaScript?
- What is the difference between debounce and throttle?
- What are the different ways to clone an object?
- How does garbage collection work in JavaScript?
- What is the use of the
argumentsobject?
- What is memory leak and how can you prevent it?
- Explain the concept of closures with an example.
- What is the difference between Object.create() and constructor functions?
- How is async/await internally implemented?
- What are generators in JavaScript?
- What is the difference between deep equality and shallow equality?
- What is the Temporal Dead Zone?
- What are WeakMap and WeakSet?
- What is tail call optimization?
- What is the module pattern in JavaScript?
- What is Service Worker in JavaScript?
- What is the difference between localStorage, sessionStorage, and cookies?
- How does JavaScript handle concurrency?
- What is the difference between a microtask and a macrotask?
- What is the purpose of Symbol in JavaScript?
- What are dynamic imports?
- What is the difference between eval() and Function() constructor?
- What is reflow and repaint in the browser?
- What is serialization and deserialization?
- How can you make a custom iterable object in JavaScript?
JavaScript has 7 primitive data types:
NumberStringBooleanUndefinedNullSymbolBigInt
Non-primitive: Object (includes arrays, functions, etc.)
var: Function/global scoped, can be redeclared/updated.let: Block scoped, can be updated but not redeclared in same scope.const: Block scoped, cannot be updated/redeclared.
- Primitive: Immutable -
String,Number,Boolean,Undefined,Null,Symbol,BigInt. - Non-primitive: Mutable -
Object,Array,Function.
JS moves declarations (not initializations) to the top of their scope during compilation.
==: Loose comparison (type coercion).===: Strict comparison (no coercion, checks type + value).
- Global: Available anywhere.
- Function/Local: Inside a function.
- Block: Within
{}usinglet/const.
A function that retains access to its lexical scope even when executed outside of it.
A function passed to another function and executed after some operation completes.
null: Intentional absence of value.undefined: Variable declared but not assigned.
- NaN: Not-a-Number.
- Check:
Number.isNaN(val)orval !== val.
- Declaration: Hoisted, available before definition.
- Expression: Not hoisted, defined at runtime.
A function that runs immediately after being defined:
(function () {
console.log("IIFE");
})();- Bubbling: Event flows from child to parent (default).
- Capturing: Event flows from parent to child (useCapture = true).
- Synchronous: Blocks further execution.
- Asynchronous: Non-blocking, tasks run in parallel.
Returns a string of the operand’s type:
typeof "hello"; // "string"Strings enclosed in backticks that allow expression interpolation:
`Hello, ${name}`;Refers to the context object of the current function/execution.
bind: Returns new function with boundthis.call: Executes function with specifiedthisand args.apply: Same ascall, but args passed as array.
- Shorter syntax, no own
this. - Suitable for callbacks and preserving context.
- Truthy:
"0",1,[],{}, etc. - Falsy:
0,"",null,undefined,NaN,false.
The event loop is a mechanism that handles asynchronous code execution. It monitors the call stack and task queue, and once the call stack is empty, it pushes queued callbacks (like from setTimeout, Promises, or events) onto the stack for execution. This ensures non-blocking behavior in JavaScript.
setTimeout(fn, delay): Executesfnonce after the specifieddelay.setInterval(fn, delay): Repeatedly executesfneverydelaymilliseconds until stopped withclearInterval.
setTimeout(() => console.log("After 2s"), 2000);
setInterval(() => console.log("Every 2s"), 2000);- Shallow copy: Copies only the top-level values. Nested objects are still referenced.
- Deep copy: Recursively copies all levels, creating independent nested structures.
let shallow = [...array];
let deep = JSON.parse(JSON.stringify(object));A Promise represents a future value from an asynchronous operation. It has three states:
- Pending
- Fulfilled
- Rejected
Handled via .then(), .catch(), and .finally().
new Promise((resolve, reject) => {
// async task
}).then(...).catch(...);async/await is syntactic sugar over Promises. It makes asynchronous code look synchronous and improves readability.
async function getData() {
const res = await fetch(url);
const data = await res.json();
return data;
}Destructuring allows unpacking values from arrays or objects into variables.
const { name, age } = { name: "Alice", age: 25 };- Spread (
...): Expands elements of an array/object. - Rest (
...): Gathers multiple elements into one.
let newArr = [...arr, 4];
function sum(...nums) {
return nums.reduce((a, b) => a + b);
}for: Traditional loop over indices.for...in: Iterates over object keys.for...of: Iterates over iterable values (arrays, strings).
for (let i = 0; i < arr.length; i++) {}
for (let key in obj) {
}
for (let value of arr) {
}map(): Transforms elements.filter(): Selects elements.reduce(): Combines elements.
nums.map((x) => x * 2);
nums.filter((x) => x > 0);
nums.reduce((a, b) => a + b, 0);JavaScript objects inherit from a prototype. If a property isn't found on an object, it's looked up in the prototype chain.
Object: Keys must be strings or symbols.Map: Keys can be any type and preserves insertion order.
let map = new Map();
map.set("key", "value");try...catch: Catches runtime errors.throw: Manually raise errors.finally: Runs always.
try {
throw new Error("Oops");
} catch (e) {
console.error(e);
} finally {
console.log("Done");
}Object.freeze(): Prevents all changes.Object.seal(): Allows value change but not addition/removal of properties.
Functions that accept or return other functions.
function apply(a, b, fn) {
return fn(a, b);
}A function that:
- Returns the same output for the same input.
- Has no side effects.
Transforming a function with multiple arguments into a sequence of unary functions.
const add = (x) => (y) => x + y;
add(5)(3); // 8- Debounce: Delays execution until inactivity.
- Throttle: Limits execution to once per interval.
- Shallow:
Object.assign({}, obj)or{...obj} - Deep:
JSON.parse(JSON.stringify(obj))
JS automatically removes unreachable memory (no references left) via garbage collection.
Available inside functions, it holds all passed arguments.
function sum() {
return [...arguments].reduce((a, b) => a + b);
}A memory leak occurs when memory that is no longer needed is not released. In JavaScript, it can happen if there are lingering references to objects. To prevent it:
- Remove event listeners when they are no longer needed.
- Avoid global variables.
- Nullify references to unused objects or elements.
A closure occurs when a function retains access to variables from its lexical scope, even after the outer function has finished executing.
Example:
function outer() {
let counter = 0;
return function inner() {
counter++;
console.log(counter);
};
}
const increment = outer();
increment(); // 1
increment(); // 2In this case, inner() has access to counter even after outer() has finished executing.
- Object.create(): Creates a new object with a specified prototype.
- Constructor functions: A function used to create objects with
thiskeyword and initialize their properties.
// Object.create()
let obj1 = Object.create({ name: "John" });
// Constructor function
function Person(name) {
this.name = name;
}
let person1 = new Person("John");async/await is syntactic sugar over Promises. Internally, async functions return a Promise. When await is used, the function execution pauses until the Promise resolves or rejects, without blocking the main thread.
A generator is a function that can be paused and resumed, allowing for asynchronous-like behavior without callbacks or promises. It uses function* syntax and yield to pause execution.
Example:
function* count() {
yield 1;
yield 2;
yield 3;
}
const gen = count();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }- Shallow equality compares object references, meaning if objects are nested, only the top-level properties are checked.
- Deep equality compares both top-level and nested properties recursively to ensure the objects are identical.
The Temporal Dead Zone (TDZ) is the period between entering the scope and the actual declaration of a variable. During this time, accessing the variable results in a ReferenceError.
Example:
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 5;- WeakMap: A collection of key-value pairs where keys are objects, and values can be any type. It does not prevent garbage collection of keys when they are no longer referenced.
- WeakSet: A collection of unique objects. Like
WeakMap, it does not prevent garbage collection.
Tail call optimization (TCO) is an optimization technique where the last call in a function is optimized to avoid creating a new stack frame, allowing recursion without growing the call stack.
Example:
function factorial(n, acc = 1) {
if (n === 0) return acc;
return factorial(n - 1, n * acc); // Tail call
}The module pattern encapsulates functionality and creates private variables and methods, exposing only the necessary parts of the module.
Example:
const counterModule = (function () {
let count = 0;
return {
increment: function () {
count++;
},
getCount: function () {
return count;
},
};
})();A Service Worker is a script that runs in the background, separate from the web page, and is used for caching assets, handling push notifications, and enabling offline functionality.
- localStorage: Stores data with no expiration time. Data persists across sessions.
- sessionStorage: Stores data for the duration of the page session. It is cleared when the page is closed.
- Cookies: Stores data with a specific expiration date and can be sent with every HTTP request.
JavaScript uses an event loop to handle concurrency. It runs tasks asynchronously by adding them to a queue and processes them when the call stack is empty.
- Microtasks: Small tasks that are executed after the current script finishes but before rendering. Promises'
.then(),.catch(), and.finally()are microtasks. - Macrotasks: Larger tasks like
setTimeout()andsetInterval(), which are executed after microtasks.
A Symbol is a primitive data type used to create unique identifiers for object properties. It ensures that property names are unique, avoiding name collisions.
Example:
const id = Symbol("id");
let obj = { [id]: 123 };Dynamic imports allow you to load modules at runtime instead of during the initial loading. This helps with lazy loading.
Example:
import("./myModule").then((module) => {
module.default();
});- eval(): Executes JavaScript code represented as a string.
- Function() constructor: Creates a new function from a string, but does not execute the code immediately.
- Reflow: The process of recalculating the layout of the webpage (e.g., resizing elements).
- Repaint: The process of re-rendering elements without affecting the layout (e.g., changing color).
- Serialization: The process of converting an object into a format (usually JSON) that can be easily stored or transmitted.
- Deserialization: The process of converting the serialized format back into an object.
To make an object iterable, you need to define the Symbol.iterator method. This method should return an iterator with next() method.
Example:
const myIterable = {
data: [1, 2, 3],
[Symbol.iterator]: function () {
let index = 0;
return {
next: () => {
if (index < this.data.length) {
return { value: this.data[index++], done: false };
}
return { done: true };
},
};
},
};