Top 100 JavaScript Interview Questions

๐Ÿ“š 100 Questions  โ€ข  โฑ ~50 min read  โ€ข  Fresherโ€“Advanced

The most comprehensive JavaScript interview guide for Anna University freshers and web developers. Covers every topic asked at TCS, Infosys, Wipro, Cognizant, HCL and product startups โ€” from basic variables to async/await and the event loop.

Q1What is JavaScript? What are its main features?Easy▼

JavaScript is a lightweight, interpreted, single-threaded programming language used to make web pages interactive. It runs in the browser (client-side) and also on servers via Node.js.

Main features:

  • Dynamic typing โ€” variable types are determined at runtime
  • Prototype-based OOP โ€” objects inherit from other objects
  • First-class functions โ€” functions are values that can be passed around
  • Event-driven โ€” responds to user actions and browser events
  • Single-threaded โ€” one task runs at a time, uses async for concurrency
Q2What is the difference between var, let, and const?Easy▼
var x = 1;   // function-scoped, hoisted, can be re-declared
let y = 2;   // block-scoped, not hoisted*, can be reassigned
const z = 3; // block-scoped, not hoisted*, cannot be reassigned
  • var: function-scoped. Hoisted to the top (initialised as undefined). Can be re-declared and reassigned. Avoid in modern JS.
  • let: block-scoped ({ }). In the "temporal dead zone" until declaration. Can be reassigned but not re-declared.
  • const: block-scoped. Must be assigned at declaration. Cannot be reassigned. Arrays/objects declared with const CAN be mutated (the binding is constant, not the value).

Rule of thumb: Always use const. Use let only when you need to reassign. Never use var.

Q3What are the JavaScript data types?Easy▼

Primitive types (7): string, number, boolean, undefined, null, bigint, symbol

Reference type (1): object (includes arrays, functions, dates)

typeof "hello"     // "string"
typeof 42          // "number"
typeof true        // "boolean"
typeof undefined   // "undefined"
typeof null        // "object"  โ† famous JS bug
typeof []          // "object"
typeof {}          // "object"
typeof function(){} // "function"

Primitives are stored by value. Objects are stored by reference.

Q4What is the difference between == and ===?Easy▼

== (loose equality) compares values after type coercion. === (strict equality) compares both value AND type โ€” no coercion.

0 == false    // true  (false coerced to 0)
0 === false   // false (different types)
"" == false   // true
null == undefined  // true
null === undefined // false

Always use === to avoid unexpected bugs from type coercion.

Q5What is null vs undefined?Easy▼
  • undefined: A variable has been declared but not assigned a value. JavaScript sets it automatically.
  • null: An intentional absence of value. You set it explicitly to mean "no value".
let a;         // undefined (automatic)
let b = null;  // null (intentional)

typeof undefined // "undefined"
typeof null      // "object" (historical bug)
Q6What is hoisting in JavaScript?Medium▼

Hoisting is JavaScript's behaviour of moving declarations to the top of their scope before code runs. Only the declaration is hoisted โ€” not the assignment.

console.log(x); // undefined (not ReferenceError)
var x = 5;

// What JS actually sees:
var x;          // hoisted
console.log(x); // undefined
x = 5;

Function declarations are fully hoisted (including the body):

greet(); // "Hello" โ€” works!
function greet() { console.log("Hello"); }

let/const are hoisted but NOT initialised โ€” accessing them before declaration throws a ReferenceError (Temporal Dead Zone).

Q7What is type coercion? Give examples.Medium▼

Type coercion is JavaScript automatically converting one type to another. Can be implicit (automatic) or explicit (manual).

// Implicit coercion
"5" + 3     // "53" (number โ†’ string, + is concat)
"5" - 3     // 2    (string โ†’ number, - is math)
true + 1    // 2    (true โ†’ 1)
false + 1   // 1    (false โ†’ 0)
"" + false  // "false"

// Explicit coercion
Number("5")   // 5
String(42)    // "42"
Boolean(0)    // false
Boolean("")   // false
Boolean("hi") // true
Q8What are truthy and falsy values in JavaScript?Easy▼

Falsy values โ€” evaluate to false in a boolean context: false, 0, "" (empty string), null, undefined, NaN

Truthy values โ€” everything else: "0", [], {}, -1, "false"

if ([]) console.log("truthy"); // prints โ€” empty array is truthy!
if ("") console.log("runs");   // doesn't run โ€” empty string is falsy
Q9What is NaN? How do you check for it?Easy▼

NaN (Not a Number) is the result of an invalid math operation. It's of type number.

typeof NaN        // "number" (confusingly!)
NaN === NaN       // false  (NaN is not equal to itself)
isNaN("hello")    // true (coerces first โ€” unreliable)
Number.isNaN(NaN) // true (best โ€” no coercion)

Always use Number.isNaN() to check for NaN reliably.

Q10What is the difference between null, undefined, and undeclared?Medium▼
  • null โ€” declared, assigned intentionally as "no value"
  • undefined โ€” declared, but never assigned
  • undeclared โ€” never declared at all; accessing it throws ReferenceError
let a = null;   // null
let b;          // undefined
console.log(c); // ReferenceError: c is not defined
Q11What is the spread operator (...)?Easy▼

Spread expands an iterable (array, string, object) into individual elements.

const a = [1, 2, 3];
const b = [...a, 4, 5];   // [1, 2, 3, 4, 5]

const obj = { x: 1 };
const obj2 = { ...obj, y: 2 }; // { x:1, y:2 }

// Copy array (shallow)
const copy = [...a];

// Pass array as function args
Math.max(...a); // 3
Q12What is destructuring assignment?Easy▼

Destructuring extracts values from arrays or properties from objects into variables.

// Array destructuring
const [first, second] = [10, 20, 30];
// first=10, second=20

// Object destructuring
const { name, age } = { name: "Priya", age: 22 };
// name="Priya", age=22

// Rename on destructure
const { name: studentName } = { name: "Kumar" };
// studentName="Kumar"

// Default values
const { x = 0, y = 0 } = { x: 5 };
// x=5, y=0
Q13What are template literals?Easy▼

Template literals (backtick strings) support embedded expressions and multi-line strings.

const name = "Priya";
const age = 22;

// Old way
const msg1 = "Hello " + name + ", you are " + age;

// Template literal
const msg2 = `Hello ${name}, you are ${age}`;

// Multi-line
const html = `
  <div>
    <h1>${name}</h1>
  </div>
`;
Q14What is short-circuit evaluation?Medium▼

Logical operators stop evaluating as soon as the result is determined.

// &&: returns first falsy OR last value
false && someFunction()  // false (someFunction not called)
true && "hello"          // "hello"

// ||: returns first truthy OR last value
null || "default"        // "default"
"value" || "default"     // "value"

// ?? (nullish coalescing): returns right side only if left is null/undefined
null ?? "fallback"       // "fallback"
0 ?? "fallback"          // 0 (0 is not null/undefined)

Common use: const name = user?.name ?? "Guest";

Q15What is optional chaining (?.)?Medium▼

Optional chaining safely accesses nested properties without throwing if a reference is null or undefined.

const user = { address: { city: "Chennai" } };

// Without optional chaining (can throw)
user.address.city        // "Chennai"
user.phone.number        // TypeError!

// With optional chaining (returns undefined instead)
user?.address?.city      // "Chennai"
user?.phone?.number      // undefined (no error)
user?.getName?.()        // undefined (method call)
Q16What is the difference between a function declaration and a function expression?Easy▼
// Function declaration โ€” hoisted fully
function greet(name) { return "Hello " + name; }
greet("Priya"); // works even before declaration in code

// Function expression โ€” NOT hoisted
const greet = function(name) { return "Hello " + name; };

// Arrow function expression
const greet = (name) => "Hello " + name;

Key difference: Function declarations are hoisted (can be called before they appear in code). Function expressions are not โ€” calling before assignment throws a TypeError.

Q17What is an arrow function? How is it different from a regular function?Easy▼
// Regular function
function add(a, b) { return a + b; }

// Arrow function โ€” same but shorter
const add = (a, b) => a + b;

// Single param โ€” parens optional
const double = n => n * 2;

// No params
const greet = () => "Hello!";

Key differences:

  • Arrow functions have no own this โ€” they inherit this from the enclosing scope
  • Arrow functions cannot be used as constructors (no new)
  • No arguments object
  • Cannot be used as generator functions
Q18What is a closure? Give a practical example.Medium▼

A closure is a function that remembers the variables from its outer scope even after the outer function has finished executing.

function makeCounter() {
  let count = 0;       // outer variable
  return function() {  // inner function = closure
    count++;
    return count;
  };
}

const counter = makeCounter();
counter(); // 1
counter(); // 2
counter(); // 3  โ† count is "closed over"

Practical uses: data privacy, factory functions, callback functions, React hooks (useState uses closures internally).

Q19What is scope in JavaScript? What are the types?Medium▼

Scope determines where a variable can be accessed.

  • Global scope โ€” accessible everywhere
  • Function scope โ€” accessible only inside the function (var)
  • Block scope โ€” accessible only inside { } (let, const)
  • Module scope โ€” accessible only within the module file
let global = "I'm global";

function outer() {
  let outerVar = "outer";
  function inner() {
    let innerVar = "inner";
    console.log(global);   // โœ“ accessible
    console.log(outerVar); // โœ“ accessible (closure)
    console.log(innerVar); // โœ“ accessible
  }
  // innerVar not accessible here
}
Q20What is the this keyword? How does it work?Hard▼

this refers to the object that is calling the function. Its value depends on HOW the function is called:

// 1. Global context โ†’ window (browser) or undefined (strict mode)
console.log(this); // window

// 2. Object method โ†’ the object
const obj = { name: "Priya", greet() { console.log(this.name); } };
obj.greet(); // "Priya"

// 3. Arrow function โ†’ inherits from outer scope
const obj2 = {
  name: "Kumar",
  greet: () => console.log(this.name) // โ† outer this (window)
};
obj2.greet(); // undefined (arrow has no own this)

// 4. Constructor โ†’ the new object
function Person(name) { this.name = name; }
const p = new Person("Ravi"); // this = p

// 5. call/apply/bind โ†’ explicitly set
function greet() { console.log(this.name); }
greet.call({ name: "Anitha" }); // "Anitha"
Q21What are call, apply, and bind?Hard▼

All three let you set the this value of a function explicitly:

function greet(greeting, punctuation) {
  return `${greeting}, ${this.name}${punctuation}`;
}
const user = { name: "Priya" };

// call โ€” invoke immediately, args comma-separated
greet.call(user, "Hello", "!");   // "Hello, Priya!"

// apply โ€” invoke immediately, args as array
greet.apply(user, ["Hi", "."]);   // "Hi, Priya."

// bind โ€” returns a NEW function, doesn't invoke
const greetPriya = greet.bind(user, "Hey");
greetPriya("?"); // "Hey, Priya?"
Q22What is an Immediately Invoked Function Expression (IIFE)?Medium▼

An IIFE is a function that runs immediately after it's defined. Used to create a private scope and avoid polluting the global scope.

(function() {
  const secret = "I only exist in here";
  console.log("IIFE ran!");
})();

// Arrow function IIFE
(() => {
  console.log("Arrow IIFE");
})();

Common in older JS libraries (jQuery, etc.) before ES modules. Still useful for avoiding variable conflicts.

Q23What is a higher-order function?Medium▼

A higher-order function is a function that either takes another function as an argument or returns a function.

// Takes a function as argument
[1, 2, 3].map(n => n * 2);    // [2, 4, 6]
[1, 2, 3].filter(n => n > 1); // [2, 3]

// Returns a function
function multiplier(factor) {
  return (number) => number * factor;
}
const double = multiplier(2);
double(5); // 10
double(8); // 16
Q24What is currying in JavaScript?Hard▼

Currying transforms a function with multiple arguments into a sequence of functions each taking one argument.

// Normal function
function add(a, b, c) { return a + b + c; }
add(1, 2, 3); // 6

// Curried version
function curriedAdd(a) {
  return function(b) {
    return function(c) {
      return a + b + c;
    };
  };
}
curriedAdd(1)(2)(3); // 6

// Arrow function shorthand
const add = a => b => c => a + b + c;
const add5 = add(5); // partially applied
add5(3)(2);          // 10
Q25What is a pure function?Medium▼

A pure function: (1) always returns the same output for the same input, (2) has no side effects (doesn't modify external state).

// Pure โ€” same input always gives same output
function add(a, b) { return a + b; }

// Impure โ€” reads/modifies external state
let total = 0;
function addToTotal(n) { total += n; } // side effect!

// Impure โ€” result depends on external state
function getTime() { return Date.now(); } // different each call

Pure functions are easier to test, debug, and reason about. React components should be pure functions of their props.

Q26What is memoization?Hard▼

Memoization is caching the result of a function call so the same computation isn't repeated for the same arguments.

function memoize(fn) {
  const cache = {};
  return function(...args) {
    const key = JSON.stringify(args);
    if (cache[key] !== undefined) {
      return cache[key]; // return cached result
    }
    cache[key] = fn(...args);
    return cache[key];
  };
}

function slowSquare(n) { /* expensive */ return n * n; }

const fastSquare = memoize(slowSquare);
fastSquare(100); // computed
fastSquare(100); // returned from cache instantly
Q27What is the difference between setTimeout and setInterval?Easy▼
// setTimeout โ€” runs once after a delay
const id = setTimeout(() => console.log("Ran once"), 1000);
clearTimeout(id); // cancel before it fires

// setInterval โ€” runs repeatedly at interval
const id2 = setInterval(() => console.log("Every second"), 1000);
clearInterval(id2); // stop repeating

Note: The delay is a minimum โ€” not guaranteed. If the call stack is busy, the timer fires when JS is free. Both are part of the Web API (browser), not JavaScript itself.

Q28What is a callback function?Easy▼

A callback is a function passed as an argument to another function and executed later (often after an async operation).

function greet(name, callback) {
  console.log("Hello " + name);
  callback();
}
greet("Priya", () => console.log("Callback ran!"));

// Async callback
setTimeout(() => console.log("After 1 second"), 1000);

// Array methods use callbacks
[1,2,3].forEach(n => console.log(n));

Callback hell: deeply nested callbacks become hard to read. Solved by Promises and async/await.

Q29What is the difference between synchronous and asynchronous code?Medium▼

Synchronous: code runs line by line, blocking until each line completes.

Asynchronous: code is scheduled to run later โ€” current execution continues without waiting.

// Synchronous
console.log("1");
console.log("2");
console.log("3");
// Output: 1, 2, 3

// Asynchronous
console.log("1");
setTimeout(() => console.log("2"), 0);
console.log("3");
// Output: 1, 3, 2  โ† setTimeout goes to callback queue

JavaScript is single-threaded โ€” the event loop handles async operations.

Q30What is the difference between function.length and arguments.length?Medium▼
function example(a, b, c = 0) {}

example.length    // 2 โ€” number of params WITHOUT defaults
arguments.length  // actual args passed when called

function test() {
  console.log(arguments.length);
}
test(1, 2, 3); // 3

arguments is an array-like object (not a real array) available in regular functions. Arrow functions do NOT have arguments.

Q31What are default parameters?Easy▼
function greet(name = "Guest", greeting = "Hello") {
  return `${greeting}, ${name}!`;
}
greet();               // "Hello, Guest!"
greet("Priya");        // "Hello, Priya!"
greet("Priya", "Hi"); // "Hi, Priya!"

Default parameters are only used when the argument is undefined โ€” not when it's null or 0.

Q32What is the rest parameter (...args)?Easy▼
function sum(...numbers) {
  return numbers.reduce((acc, n) => acc + n, 0);
}
sum(1, 2, 3, 4); // 10

function first(a, b, ...rest) {
  console.log(a);    // 1
  console.log(b);    // 2
  console.log(rest); // [3, 4, 5]
}
first(1, 2, 3, 4, 5);

Unlike arguments, rest parameters ARE a real array. Must be the last parameter.

Q33What is a generator function?Hard▼

Generator functions can pause execution and resume later. They use function* and yield.

function* counter() {
  yield 1;
  yield 2;
  yield 3;
}

const gen = counter();
gen.next(); // { value: 1, done: false }
gen.next(); // { value: 2, done: false }
gen.next(); // { value: 3, done: false }
gen.next(); // { value: undefined, done: true }

Used for lazy evaluation, infinite sequences, and async control flow.

Q34What is the difference between map, filter, and reduce?Medium▼
const nums = [1, 2, 3, 4, 5];

// map โ€” transforms each element, same length
nums.map(n => n * 2);          // [2, 4, 6, 8, 10]

// filter โ€” keeps elements that pass a test
nums.filter(n => n % 2 === 0); // [2, 4]

// reduce โ€” accumulates to a single value
nums.reduce((sum, n) => sum + n, 0); // 15

// Chained
nums
  .filter(n => n > 2)     // [3, 4, 5]
  .map(n => n * 10)        // [30, 40, 50]
  .reduce((a, b) => a + b, 0); // 120
Q35What is a debounce function? Give a use case.Hard▼

Debounce delays the execution of a function until after a period of inactivity. Useful for search inputs, resize handlers.

function debounce(fn, delay) {
  let timer;
  return function(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}

// Search input โ€” only fires after user stops typing 300ms
const search = debounce((query) => {
  fetch(`/api/search?q=${query}`);
}, 300);

input.addEventListener("input", e => search(e.target.value));
Q36What is the difference between shallow copy and deep copy?Medium▼

Shallow copy: copies the top-level properties. Nested objects still share the same reference.

Deep copy: copies everything recursively โ€” no shared references.

const original = { a: 1, nested: { b: 2 } };

// Shallow copy โ€” nested.b is still shared
const shallow = { ...original };
shallow.nested.b = 99;
console.log(original.nested.b); // 99 โ† mutated!

// Deep copy โ€” truly independent
const deep = JSON.parse(JSON.stringify(original));
deep.nested.b = 99;
console.log(original.nested.b); // 2 โ† safe

JSON method doesn't handle functions, undefined, or circular references. Use structuredClone() (modern) or a library like lodash's _.cloneDeep().

Q37How do you remove duplicates from an array?Easy▼
const arr = [1, 2, 2, 3, 3, 4];

// Method 1: Set (fastest, most readable)
const unique = [...new Set(arr)]; // [1, 2, 3, 4]

// Method 2: filter + indexOf
const unique2 = arr.filter((v, i) => arr.indexOf(v) === i);

// Method 3: reduce
const unique3 = arr.reduce((acc, v) => {
  return acc.includes(v) ? acc : [...acc, v];
}, []);
Q38What is the difference between slice and splice?Easy▼
const arr = [1, 2, 3, 4, 5];

// slice(start, end) โ€” returns new array, doesn't mutate
arr.slice(1, 3);  // [2, 3]  (index 1 up to but not including 3)
arr.slice(-2);    // [4, 5]  (last 2 elements)
// arr is still [1, 2, 3, 4, 5]

// splice(start, deleteCount, ...items) โ€” MUTATES original
arr.splice(1, 2);        // removes 2 elements at index 1 โ†’ [2, 3]
// arr is now [1, 4, 5]
arr.splice(1, 0, 99, 98); // inserts at index 1, deletes 0

Memory tip: slice = non-destructive. splice = destructive (like surgery).

Q39How do you flatten a nested array?Medium▼
const nested = [1, [2, 3], [4, [5, 6]]];

// flat(depth) โ€” default depth 1
nested.flat();    // [1, 2, 3, 4, [5, 6]]
nested.flat(2);   // [1, 2, 3, 4, 5, 6]
nested.flat(Infinity); // fully flatten any depth

// flatMap โ€” map then flat(1)
[1, 2, 3].flatMap(n => [n, n * 2]);
// [1, 2, 2, 4, 3, 6]
Q40What is Object.keys(), Object.values(), Object.entries()?Easy▼
const user = { name: "Priya", age: 22, city: "Chennai" };

Object.keys(user);    // ["name", "age", "city"]
Object.values(user);  // ["Priya", 22, "Chennai"]
Object.entries(user); // [["name","Priya"], ["age",22], ["city","Chennai"]]

// Iterate with entries
for (const [key, value] of Object.entries(user)) {
  console.log(`${key}: ${value}`);
}
Q41What is Object.freeze() vs Object.seal()?Hard▼
const obj = { x: 1, y: 2 };

// freeze โ€” no add, no delete, no modify
Object.freeze(obj);
obj.x = 99;    // silently fails (throws in strict mode)
obj.z = 3;     // silently fails
delete obj.x;  // silently fails
// obj is still { x: 1, y: 2 }

const obj2 = { a: 1, b: 2 };
// seal โ€” no add, no delete, but CAN modify
Object.seal(obj2);
obj2.a = 99;   // โœ“ works
obj2.c = 3;    // โœ— fails (no new props)
delete obj2.a; // โœ— fails
Q42What is prototypal inheritance?Hard▼

Every JavaScript object has a hidden [[Prototype]] link to another object. When you access a property, JS looks up the prototype chain until it finds it (or returns undefined).

const animal = {
  speak() { return `${this.name} makes a sound`; }
};

const dog = Object.create(animal); // dog's prototype = animal
dog.name = "Rex";
dog.speak(); // "Rex makes a sound" โ† inherited from animal

// Prototype chain:
// dog โ†’ animal โ†’ Object.prototype โ†’ null

Classes in JS are syntax sugar over prototypal inheritance.

Q43What is the difference between for...in and for...of?Medium▼
const arr = [10, 20, 30];
const obj = { a: 1, b: 2 };

// for...in โ€” iterates over keys (property names)
for (const key in obj) console.log(key);   // "a", "b"
for (const i in arr)   console.log(i);     // "0", "1", "2" (indices as strings)

// for...of โ€” iterates over values (iterables: arrays, strings, Sets, Maps)
for (const val of arr) console.log(val);   // 10, 20, 30
for (const ch of "hi") console.log(ch);    // "h", "i"
// for...of on plain objects throws โ€” not iterable
Q44What is a Map vs a plain Object?Medium▼
// Object โ€” keys must be strings/symbols
const obj = { name: "Priya" };

// Map โ€” any type as key, insertion order preserved
const map = new Map();
map.set("name", "Priya");
map.set(42, "number key");
map.set({ id: 1 }, "object key");

map.get("name");  // "Priya"
map.size;         // 3
map.has("name");  // true
map.delete("name");
map.forEach((val, key) => console.log(key, val));

Use Map when: keys are non-strings, you need insertion order, or frequent add/delete operations.

Q45What is a Set in JavaScript?Easy▼
const set = new Set([1, 2, 2, 3, 3]);
// Set {1, 2, 3} โ€” only unique values

set.add(4);      // Set {1, 2, 3, 4}
set.has(2);      // true
set.delete(2);   // removes 2
set.size;        // 3

// Convert to array
[...set];        // [1, 3, 4]

// Remove duplicates from array
const unique = [...new Set([1,2,2,3])];
Q46How do you sort an array of objects by a property?Medium▼
const students = [
  { name: "Priya", marks: 88 },
  { name: "Kumar", marks: 92 },
  { name: "Ravi",  marks: 75 }
];

// Sort by marks ascending
students.sort((a, b) => a.marks - b.marks);

// Sort by marks descending
students.sort((a, b) => b.marks - a.marks);

// Sort by name alphabetically
students.sort((a, b) => a.name.localeCompare(b.name));

Note: sort() mutates the original array. Use [...students].sort() for a non-destructive sort.

Q47What is Array.from() used for?Medium▼
// Convert array-like or iterable to real array
Array.from("hello");           // ["h","e","l","l","o"]
Array.from({ length: 3 });     // [undefined, undefined, undefined]
Array.from({ length: 3 }, (_, i) => i + 1); // [1, 2, 3]
Array.from(new Set([1,2,3]));  // [1, 2, 3]

// Convert NodeList to array
Array.from(document.querySelectorAll("p"));
Q48What is the difference between find() and filter()?Easy▼
const users = [
  { id: 1, name: "Priya" },
  { id: 2, name: "Kumar" },
  { id: 3, name: "Priya" }
];

// find โ€” returns FIRST match (one item or undefined)
users.find(u => u.name === "Priya");
// { id: 1, name: "Priya" }

// filter โ€” returns ALL matches (array)
users.filter(u => u.name === "Priya");
// [{ id:1, name:"Priya" }, { id:3, name:"Priya" }]
Q49What is some() vs every()?Easy▼
const scores = [45, 82, 90, 55, 78];

// some โ€” true if AT LEAST ONE passes
scores.some(s => s >= 90);   // true
scores.some(s => s >= 100);  // false

// every โ€” true if ALL pass
scores.every(s => s >= 40);  // true
scores.every(s => s >= 80);  // false

Both short-circuit: some stops at first true; every stops at first false.

Q50What is optional chaining with arrays and methods?Medium▼
const data = null;

data?.users             // undefined (no error)
data?.users?.[0]        // undefined
data?.getName?.()       // undefined (safe method call)

// With arrays
const arr = null;
arr?.[0]   // undefined

const user = { getName: () => "Priya" };
user.getName?.()   // "Priya"
user.getAge?.()    // undefined (method doesn't exist)
Q51How do you check if a value is an array?Easy▼
Array.isArray([1, 2, 3]);   // true โœ“ (best way)
Array.isArray({});           // false
Array.isArray("hello");      // false

// Don't use typeof โ€” it says "object" for arrays
typeof [];   // "object"

// instanceof also works but can fail across iframes
[] instanceof Array; // true
Q52What is object shorthand syntax in ES6?Easy▼
const name = "Priya";
const age = 22;

// Old way
const user = { name: name, age: age };

// ES6 shorthand โ€” when key === variable name
const user = { name, age };

// Method shorthand
const obj = {
  greet() { return "Hello"; },       // instead of greet: function() {}
  get fullName() { return "Priya"; } // getter
};
Q53What are computed property names?Medium▼
const key = "name";
const suffix = "Score";

const obj = {
  [key]: "Priya",          // { name: "Priya" }
  [`math${suffix}`]: 95,   // { mathScore: 95 }
};

// Dynamic form field handler
function handleChange(field, value) {
  setState(prev => ({ ...prev, [field]: value }));
}
Q54What is JSON.stringify() and JSON.parse()?Easy▼
const user = { name: "Priya", age: 22, active: true };

// Stringify โ€” JS object โ†’ JSON string
const json = JSON.stringify(user);
// '{"name":"Priya","age":22,"active":true}'

// Stringify with formatting (for readability)
JSON.stringify(user, null, 2);

// Parse โ€” JSON string โ†’ JS object
const back = JSON.parse(json);
back.name; // "Priya"

// Gotchas: undefined, functions, symbols are stripped
JSON.stringify({ fn: () => {}, x: undefined }); // '{}'
Q55What is the difference between Object.assign() and the spread operator for objects?Medium▼
const a = { x: 1 };
const b = { y: 2 };

// Object.assign โ€” mutates target, returns target
const merged1 = Object.assign({}, a, b); // { x:1, y:2 }
Object.assign(a, b); // mutates a!

// Spread โ€” always creates a new object
const merged2 = { ...a, ...b }; // { x:1, y:2 }

// Both do shallow copy
// If properties have the same key, later one wins:
const c = { x: 1, y: 2 };
const d = { y: 99, z: 3 };
const merged3 = { ...c, ...d }; // { x:1, y:99, z:3 }
Q56What is the JavaScript event loop?Hard▼

The event loop is what allows JavaScript to be non-blocking despite being single-threaded.

  • Call Stack โ€” where synchronous code runs (LIFO)
  • Web APIs โ€” browser handles async (setTimeout, fetch, DOM events)
  • Callback Queue โ€” callbacks waiting to run (setTimeout etc.)
  • Microtask Queue โ€” Promise callbacks (higher priority than callback queue)
  • Event Loop โ€” moves tasks from queues to call stack when stack is empty
console.log("1");
setTimeout(() => console.log("2"), 0);
Promise.resolve().then(() => console.log("3"));
console.log("4");
// Output: 1, 4, 3, 2
// Microtasks (Promise) run before macrotasks (setTimeout)
Q57What is a Promise? What are its states?Medium▼

A Promise represents the eventual result of an async operation. Has 3 states:

  • pending โ€” initial state, neither fulfilled nor rejected
  • fulfilled โ€” operation completed successfully
  • rejected โ€” operation failed
const promise = new Promise((resolve, reject) => {
  const success = true;
  if (success) resolve("Data loaded!");
  else reject(new Error("Failed!"));
});

promise
  .then(data => console.log(data))    // fulfilled
  .catch(err => console.log(err))     // rejected
  .finally(() => console.log("Done")); // always runs
Q58What is async/await? How does it work?Medium▼

async/await is syntactic sugar over Promises โ€” makes async code look synchronous.

// With Promises
function getData() {
  return fetch("/api/data")
    .then(res => res.json())
    .then(data => data)
    .catch(err => console.error(err));
}

// With async/await โ€” cleaner
async function getData() {
  try {
    const res = await fetch("/api/data");
    const data = await res.json();
    return data;
  } catch (err) {
    console.error(err);
  }
}

// await pauses execution of the async function
// The rest of the program continues
Q59What is Promise.all() vs Promise.allSettled()?Hard▼
const p1 = fetch("/api/users");
const p2 = fetch("/api/posts");

// Promise.all โ€” waits for ALL, FAILS FAST if any rejects
Promise.all([p1, p2])
  .then(([users, posts]) => console.log(users, posts))
  .catch(err => console.log("One failed:", err));

// Promise.allSettled โ€” waits for ALL regardless of rejection
Promise.allSettled([p1, p2])
  .then(results => {
    results.forEach(r => {
      if (r.status === "fulfilled") console.log(r.value);
      else console.log("Failed:", r.reason);
    });
  });

// Promise.race โ€” first to resolve/reject wins
// Promise.any  โ€” first to FULFILL wins (ignores rejections)
Q60What is the Fetch API?Medium▼
// GET request
const res = await fetch("https://api.example.com/users");
const users = await res.json();

// POST request
const res2 = await fetch("/api/users", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Priya", age: 22 })
});
const newUser = await res2.json();

// Error handling โ€” fetch doesn't throw on 4xx/5xx!
if (!res.ok) throw new Error(`HTTP error: ${res.status}`);

Important: fetch only rejects on network failure. HTTP 404/500 still resolve โ€” you must check res.ok.

Q61What is callback hell and how do Promises solve it?Medium▼
// Callback hell โ€” deeply nested, hard to read
getUser(id, function(user) {
  getPosts(user.id, function(posts) {
    getComments(posts[0].id, function(comments) {
      // ... keeps going
    });
  });
});

// Promises โ€” flat chain
getUser(id)
  .then(user => getPosts(user.id))
  .then(posts => getComments(posts[0].id))
  .then(comments => console.log(comments))
  .catch(err => console.error(err));

// async/await โ€” even cleaner
const user = await getUser(id);
const posts = await getPosts(user.id);
const comments = await getComments(posts[0].id);
Q62How do you run multiple async operations in parallel?Medium▼
// Sequential โ€” slow (waits for each)
const user  = await getUser(1);   // 1s
const posts = await getPosts(1);  // 1s
// Total: 2 seconds

// Parallel โ€” fast
const [user, posts] = await Promise.all([
  getUser(1),
  getPosts(1)
]);
// Total: 1 second (both run at same time)

Use Promise.all() when operations are independent and you need all results.

Q63What is localStorage vs sessionStorage?Easy▼
// localStorage โ€” persists until manually cleared
localStorage.setItem("theme", "dark");
localStorage.getItem("theme");   // "dark"
localStorage.removeItem("theme");
localStorage.clear();

// sessionStorage โ€” cleared when tab/browser closes
sessionStorage.setItem("cart", JSON.stringify([1,2,3]));
const cart = JSON.parse(sessionStorage.getItem("cart"));

Both store strings only. Both are synchronous. Max ~5MB. Not secure โ€” don't store passwords or tokens here.

Q64What are cookies? How are they different from localStorage?Medium▼
  • Cookies: sent with every HTTP request, can expire, can be HttpOnly (not accessible via JS), max 4KB
  • localStorage: not sent with requests, no expiry, JS accessible, ~5MB
// Set cookie (JS)
document.cookie = "username=Priya; expires=Fri, 31 Dec 2026 23:59:59 GMT; path=/";

// localStorage
localStorage.setItem("username", "Priya");

Cookies are better for authentication tokens (especially HttpOnly). localStorage is better for UI preferences.

Q65What is a throttle function?Hard▼

Throttle limits how often a function can run โ€” it fires at most once per time window. Unlike debounce (which delays), throttle executes immediately but caps the rate.

function throttle(fn, limit) {
  let lastRun = 0;
  return function(...args) {
    const now = Date.now();
    if (now - lastRun >= limit) {
      lastRun = now;
      fn.apply(this, args);
    }
  };
}

// Fires at most once every 200ms during scroll
window.addEventListener("scroll", throttle(() => {
  updateScrollProgress();
}, 200));

Debounce = "wait until user stops". Throttle = "run at most once per interval".

Q66What is a Web Worker?Hard▼

Web Workers run JavaScript in a background thread โ€” separate from the main UI thread. Used for heavy computations that would otherwise freeze the page.

// main.js
const worker = new Worker("worker.js");
worker.postMessage({ data: largeArray });
worker.onmessage = (e) => console.log("Result:", e.data);

// worker.js
self.onmessage = (e) => {
  const result = heavyComputation(e.data);
  self.postMessage(result);
};

Workers cannot access the DOM. Communication via postMessage.

Q67What is the difference between microtasks and macrotasks?Hard▼

Microtasks (higher priority): Promise callbacks (.then, .catch), queueMicrotask(), MutationObserver

Macrotasks (lower priority): setTimeout, setInterval, I/O events, UI rendering

console.log("start");

setTimeout(() => console.log("macro"), 0);        // macrotask
Promise.resolve().then(() => console.log("micro")); // microtask

console.log("end");

// Output: start โ†’ end โ†’ micro โ†’ macro
// ALL microtasks drain before the next macrotask runs
Q68What is an AbortController?Hard▼

AbortController cancels an in-flight fetch request.

const controller = new AbortController();
const { signal } = controller;

fetch("/api/data", { signal })
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => {
    if (err.name === "AbortError") console.log("Request cancelled");
  });

// Cancel after 3 seconds
setTimeout(() => controller.abort(), 3000);

// React example โ€” cancel fetch when component unmounts
useEffect(() => {
  const ctrl = new AbortController();
  fetchData(ctrl.signal);
  return () => ctrl.abort(); // cleanup
}, []);
Q69What is async iteration?Hard▼
// for await...of โ€” iterate over async iterables (streams, APIs)
async function fetchPages() {
  const urls = ["/page/1", "/page/2", "/page/3"];

  for await (const url of urls.map(u => fetch(u))) {
    const data = await url.json();
    console.log(data);
  }
}
Q70What does async function always return?Medium▼

An async function always returns a Promise, regardless of what you return inside.

async function getValue() {
  return 42; // wraps in Promise.resolve(42)
}

getValue(); // Promise { 42 }
getValue().then(v => console.log(v)); // 42

async function fail() {
  throw new Error("oops"); // wraps in Promise.reject(Error)
}
fail().catch(err => console.log(err.message)); // "oops"
Q71What is the difference between Promise.race() and Promise.any()?Hard▼
// race โ€” first to SETTLE (resolve OR reject) wins
Promise.race([p1, p2, p3]);
// If p2 rejects first โ†’ returns rejection

// any โ€” first to FULFILL wins, ignores rejections
Promise.any([p1, p2, p3]);
// Rejects only if ALL promises reject (AggregateError)

// Use case: race = timeout pattern
const timeout = new Promise((_, reject) =>
  setTimeout(() => reject(new Error("Timeout")), 5000)
);
const result = await Promise.race([fetch("/api/data"), timeout]);
Q72How do you handle errors in async/await?Medium▼
// Method 1: try/catch (most common)
async function loadUser(id) {
  try {
    const res = await fetch(`/api/users/${id}`);
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } catch (err) {
    console.error("Failed:", err.message);
    return null;
  }
}

// Method 2: .catch() on the async function call
const user = await loadUser(1).catch(err => null);

// Method 3: helper to avoid try/catch everywhere
async function to(promise) {
  return promise.then(data => [null, data]).catch(err => [err, null]);
}
const [err, user] = await to(fetchUser(1));
Q73What is an event emitter pattern?Hard▼
class EventEmitter {
  constructor() { this.events = {}; }

  on(event, listener) {
    (this.events[event] ??= []).push(listener);
  }

  emit(event, ...args) {
    this.events[event]?.forEach(fn => fn(...args));
  }

  off(event, listener) {
    this.events[event] = this.events[event]?.filter(fn => fn !== listener);
  }
}

const emitter = new EventEmitter();
emitter.on("data", data => console.log("Got:", data));
emitter.emit("data", { name: "Priya" }); // "Got: { name: 'Priya' }"
Q74What is the difference between XMLHttpRequest and fetch?Medium▼
  • XMLHttpRequest (XHR): older API, callback-based, verbose, supports progress events
  • fetch: modern Promise-based, cleaner syntax, no built-in progress events, better defaults
// XHR โ€” old way
const xhr = new XMLHttpRequest();
xhr.open("GET", "/api/data");
xhr.onload = () => console.log(JSON.parse(xhr.responseText));
xhr.onerror = () => console.error("Error");
xhr.send();

// fetch โ€” modern way
const data = await fetch("/api/data").then(r => r.json());

Use fetch for all new code. XHR is only needed for upload progress tracking.

Q75What is queueMicrotask()?Hard▼
// Schedules a function to run as a microtask
// (after current code, before any macrotasks/rendering)
queueMicrotask(() => console.log("microtask"));
console.log("sync");
// Output: "sync" then "microtask"

// Equivalent to:
Promise.resolve().then(() => console.log("same timing"));

Useful for deferring work without the overhead of creating a Promise.

Q76What is the DOM?Easy▼

DOM (Document Object Model) is a programming interface that represents the HTML document as a tree of nodes. Each HTML element is a node. JavaScript can read, add, change, or remove nodes dynamically.

// Document is the root
document.title;                        // page title
document.getElementById("main");      // single element by id
document.querySelector(".card");       // first match
document.querySelectorAll("p");       // all <p> elements (NodeList)
document.createElement("div");        // create new element
document.body.appendChild(newDiv);    // add to page
Q77What is event bubbling and event capturing?Hard▼

When an event occurs on an element, it goes through 3 phases:

  1. Capture phase: event goes from document down to the target
  2. Target phase: event reaches the target element
  3. Bubble phase: event bubbles up from target to document
// By default, handlers fire during bubble phase
el.addEventListener("click", handler);          // bubble
el.addEventListener("click", handler, true);    // capture

// Stop bubbling
el.addEventListener("click", (e) => {
  e.stopPropagation(); // event won't bubble up
});
Q78What is event delegation?Hard▼

Event delegation attaches ONE event listener to a parent element instead of many listeners on each child. Relies on event bubbling.

<!-- Instead of adding listener to each <li> -->
<ul id="list">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

// ONE listener on parent
document.getElementById("list").addEventListener("click", (e) => {
  if (e.target.tagName === "LI") {
    console.log("Clicked:", e.target.textContent);
  }
});

Benefits: fewer event listeners (memory efficient), works for dynamically added elements.

Q79What is e.preventDefault()?Easy▼
// Prevent a link from navigating
document.querySelector("a").addEventListener("click", (e) => {
  e.preventDefault();
  console.log("Link clicked but didn't navigate");
});

// Prevent form from submitting (to handle it with JS instead)
form.addEventListener("submit", (e) => {
  e.preventDefault();
  const data = new FormData(form);
  // handle with fetch...
});
Q80What is the difference between innerHTML, textContent, and innerText?Medium▼
const el = document.querySelector("#box");

el.innerHTML;    // full HTML markup (can include tags)
el.textContent;  // all text, including hidden elements, no tags
el.innerText;    // only visible text, respects CSS display:none

// Setting
el.innerHTML = "<strong>Bold</strong>"; // renders HTML
el.textContent = "<strong>Bold</strong>"; // shows as literal text

Security: Never set innerHTML from user input โ€” XSS risk. Use textContent for user data.

Q81How do you add and remove CSS classes with JavaScript?Easy▼
const btn = document.querySelector(".btn");

btn.classList.add("active");         // add class
btn.classList.remove("active");      // remove class
btn.classList.toggle("dark");        // add if absent, remove if present
btn.classList.contains("active");    // true/false
btn.classList.replace("old", "new"); // replace a class

// Old way (avoid)
btn.className = "btn active"; // overwrites ALL classes
Q82What is DOMContentLoaded vs load event?Medium▼
// DOMContentLoaded โ€” fires when HTML is parsed, DOM is ready
// (before images/CSS load)
document.addEventListener("DOMContentLoaded", () => {
  console.log("DOM ready โ€” safe to query elements");
});

// load โ€” fires when EVERYTHING is loaded (images, CSS, fonts)
window.addEventListener("load", () => {
  console.log("Everything loaded");
});

Use DOMContentLoaded for most JS initialization. load is for measuring page performance or working with image dimensions.

Q83What is a MutationObserver?Hard▼

MutationObserver watches for changes to the DOM tree.

const observer = new MutationObserver((mutations) => {
  mutations.forEach(m => console.log("DOM changed:", m));
});

observer.observe(document.body, {
  childList: true,     // watch for added/removed children
  subtree: true,       // watch all descendants
  attributes: true,    // watch attribute changes
  characterData: true  // watch text changes
});

// Stop observing
observer.disconnect();
Q84What is an IntersectionObserver? Give a use case.Hard▼

IntersectionObserver watches when an element enters or leaves the viewport. Used for lazy loading and infinite scroll.

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // Element is visible
      entry.target.classList.add("visible");
      observer.unobserve(entry.target); // stop watching
    }
  });
}, { threshold: 0.1 }); // 10% visible

document.querySelectorAll(".card").forEach(el => observer.observe(el));

// Lazy loading images
const imgObserver = new IntersectionObserver((entries) => {
  entries.forEach(e => {
    if (e.isIntersecting) {
      e.target.src = e.target.dataset.src;
      imgObserver.unobserve(e.target);
    }
  });
});
Q85What is getBoundingClientRect()?Medium▼
const el = document.querySelector(".card");
const rect = el.getBoundingClientRect();

rect.top;     // distance from viewport top
rect.left;    // distance from viewport left
rect.width;   // element width
rect.height;  // element height
rect.bottom;  // rect.top + rect.height
rect.right;   // rect.left + rect.width

// Check if element is in viewport
function isVisible(el) {
  const r = el.getBoundingClientRect();
  return r.top >= 0 && r.bottom <= window.innerHeight;
}
Q86What is the difference between clientWidth/offsetWidth/scrollWidth?Hard▼
  • clientWidth: content + padding (no border, no scrollbar)
  • offsetWidth: content + padding + border (no margin)
  • scrollWidth: full scrollable content width (including hidden overflow)
const el = document.querySelector(".box");
el.clientWidth;  // visible width inside borders
el.offsetWidth;  // total width including border
el.scrollWidth;  // full content width (even if overflowing)
Q87What is document.createDocumentFragment()?Hard▼

A lightweight container to batch DOM updates and append once โ€” avoids multiple reflows.

// Without fragment โ€” 100 reflows
for (let i = 0; i < 100; i++) {
  const li = document.createElement("li");
  li.textContent = `Item ${i}`;
  list.appendChild(li); // reflows each time!
}

// With fragment โ€” 1 reflow
const frag = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const li = document.createElement("li");
  li.textContent = `Item ${i}`;
  frag.appendChild(li); // no reflow
}
list.appendChild(frag); // 1 reflow
Q88What is event.target vs event.currentTarget?Medium▼
<ul id="nav">
  <li>Home</li>
  <li>About</li>
</ul>

document.getElementById("nav").addEventListener("click", (e) => {
  e.target;        // element that was CLICKED (the <li>)
  e.currentTarget; // element that has the LISTENER (the <ul>)
  this;            // same as currentTarget (for regular functions)
});

In event delegation, e.target is the actual clicked element, e.currentTarget is the delegating parent.

Q89What is a custom event?Medium▼
// Create and dispatch
const event = new CustomEvent("orderPlaced", {
  detail: { orderId: 123, total: 999 },
  bubbles: true,
  cancelable: true
});
document.getElementById("shop").dispatchEvent(event);

// Listen for it
document.addEventListener("orderPlaced", (e) => {
  console.log("Order:", e.detail.orderId); // 123
});

Custom events are great for decoupled communication between components without a framework.

Q90What is the difference between window, document, and navigator?Medium▼
  • window: global object in browser โ€” all globals live here. Contains document, location, history, setTimeout, etc.
  • document: represents the HTML document. Entry point to the DOM.
  • navigator: browser information โ€” language, user agent, online status, geolocation.
window.innerWidth;          // viewport width
document.title;             // page title
navigator.language;         // "en-US"
navigator.onLine;           // true/false
navigator.geolocation.getCurrentPosition(pos => console.log(pos));
Q91What are JavaScript Symbols?Hard▼
// Symbol โ€” unique, immutable primitive
const id1 = Symbol("id");
const id2 = Symbol("id");
id1 === id2; // false โ€” always unique

// Use as object keys (won't clash)
const ID = Symbol("id");
const user = { [ID]: 123, name: "Priya" };
user[ID]; // 123

// Symbols are not enumerable โ€” won't show in for...in or Object.keys()
Q92What is a WeakMap and WeakSet?Hard▼

WeakMap/WeakSet hold weak references โ€” entries are garbage collected when the key object has no other references. Keys must be objects.

const wm = new WeakMap();
let user = { name: "Priya" };
wm.set(user, { sessionId: "abc" });
wm.get(user); // { sessionId: "abc" }

user = null; // user object garbage collected โ†’ entry removed from WeakMap automatically

Use cases: caching per-object data, storing private data, tracking DOM nodes without memory leaks.

Q93What is a Proxy in JavaScript?Hard▼
const handler = {
  get(target, key) {
    return key in target ? target[key] : `Property "${key}" not found`;
  },
  set(target, key, value) {
    if (typeof value !== "number") throw new TypeError("Only numbers!");
    target[key] = value;
    return true;
  }
};

const obj = new Proxy({}, handler);
obj.x = 42;     // โœ“
obj.x;          // 42
obj.y;          // "Property "y" not found"
obj.z = "hi";   // TypeError!

Proxies power Vue 3's reactivity system and allow validation, logging, and virtual properties.

Q94What are ES6 modules? How are they different from CommonJS?Medium▼
// ES Modules (browser, modern Node.js)
export const PI = 3.14;
export function add(a, b) { return a + b; }
export default class Calculator { ... }

import { PI, add } from "./math.js";
import Calculator from "./math.js";
import * as Math from "./math.js";

// CommonJS (Node.js traditional)
module.exports = { PI, add };
const { PI, add } = require("./math.js");

Key differences: ES modules are static (analysed at parse time), support tree-shaking, use import/export. CommonJS is dynamic, uses require/module.exports.

Q95What is a class in JavaScript? How does it work under the hood?Medium▼
class Animal {
  #name; // private field (ES2022)

  constructor(name) { this.#name = name; }

  speak() { return `${this.#name} makes a sound`; }

  static create(name) { return new Animal(name); }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);          // must call super first
    this.breed = breed;
  }
  speak() { return super.speak() + " (Woof!)"; }
}

const dog = new Dog("Rex", "Labrador");
dog.speak(); // "Rex makes a sound (Woof!)"

Classes are syntax sugar over prototypal inheritance โ€” under the hood it's still prototypes.

Q96What is the difference between Object.create(null) and {}?Hard▼
const a = {};
// a.__proto__ = Object.prototype
// Has inherited methods: toString, hasOwnProperty, etc.
a.toString(); // "[object Object]"

const b = Object.create(null);
// b has NO prototype at all โ€” truly empty object
b.toString; // undefined
// Safer as a dictionary โ€” no inherited property conflicts

Use Object.create(null) when you need a pure dictionary with no risk of key collisions with prototype methods.

Q97What is tail call optimization?Hard▼

Tail call optimization (TCO) allows recursive functions to run without growing the call stack โ€” if the recursive call is the last operation in the function.

// Regular recursion โ€” grows stack, can overflow with large n
function sum(n) {
  if (n <= 0) return 0;
  return n + sum(n - 1); // โ† n + ... is not tail position
}

// Tail-call form โ€” accumulator pattern
function sum(n, acc = 0) {
  if (n <= 0) return acc;
  return sum(n - 1, acc + n); // โ† tail position
}

TCO is specified in ES6 but only implemented in Safari. In practice, prefer iteration over deep recursion in JS.

Q98What is the difference between composition and inheritance?Hard▼

Inheritance: "is-a" relationship. A Dog IS AN Animal. Can lead to deep, rigid hierarchies.

Composition: "has-a" relationship. Build objects by combining small, reusable behaviours.

// Composition โ€” mix in behaviours
const canSwim  = { swim: () => "swimming" };
const canFly   = { fly: () => "flying" };
const canBark  = { bark: () => "woof" };

const duck = Object.assign({}, canSwim, canFly);
const dog  = Object.assign({}, canSwim, canBark);

duck.fly();  // "flying"
dog.bark();  // "woof"

Prefer composition over inheritance โ€” it's more flexible and avoids the "fragile base class" problem.

Q99What are getters and setters in JavaScript?Medium▼
class Temperature {
  #celsius;

  constructor(celsius) { this.#celsius = celsius; }

  get fahrenheit() {
    return this.#celsius * 9/5 + 32; // computed on access
  }

  set fahrenheit(value) {
    this.#celsius = (value - 32) * 5/9;
  }

  get celsius() { return this.#celsius; }
  set celsius(value) {
    if (value < -273.15) throw new Error("Below absolute zero!");
    this.#celsius = value;
  }
}

const t = new Temperature(100);
t.fahrenheit; // 212
t.fahrenheit = 32;
t.celsius;    // 0
Q100What are some important JavaScript performance best practices?Hard▼
  • Minimize DOM access โ€” cache references: const el = document.getElementById("x"), don't query in loops
  • Batch DOM updates โ€” use DocumentFragment or class changes instead of many individual mutations
  • Use event delegation โ€” one listener on parent vs many on children
  • Debounce/throttle event handlers for scroll, resize, and input
  • Avoid memory leaks โ€” remove event listeners, clear intervals/timeouts, use WeakMap for per-object data
  • Use const โ€” signals intent and can help engine optimization
  • Lazy load heavy modules with dynamic import()
  • Prefer Map over objects for frequent add/delete operations
  • Use Web Workers for CPU-heavy tasks to avoid blocking the UI
  • Measure first โ€” use Chrome DevTools Performance tab before optimizing