Introduction

Welcome to the ultimate JavaScript interview handbook. Whether you are a college student preparing for internships, a React developer upgrading your core engineering skills, or a senior developer brushing up on internal machinery, this guide has been designed to take you from foundational basics to advanced runtime mechanics.

Instead of dry definitions, every question here includes direct, interview-ready answers, real-world analogies, code, and conceptual "follow-up" questions that tech interviewers actually use to test your depth.


Table of Contents


Difficulty Legend

🟢 Easy 🟡 Medium 🔴 Hard

🟢 Question 1: Easy

What is the difference between Primitive and Reference types?

Short Interview Answer:

Primitive types store value directly on the Stack (stack memory) and are immutable. Reference types store an address/pointer on the Stack pointing to a mutable object located in the Heap memory.

Detailed Explanation:

JavaScript memory is divided into two primary storage environments: the Stack and the Heap. Primitives like numbers, strings, and booleans are small and fixed in size. Hence, JavaScript stores them on the high-speed Stack directly. When you assign or copy a primitive, JavaScript creates a completely independent copy of that value.

Reference types like Objects, Arrays, and Functions can dynamically grow. Placing them on the Stack could choke the execution speed. Therefore, the actual contents are created in the flexible Heap, while a small, fixed-size memory reference (the address of the object in the Heap) is written onto the Stack.

Real Life Analogy:

Primitive: A physical printed book. If you give a copy of the book to your friend, they can highlight pages in theirs, but your copy remains completely untouched.

Reference: A shared Google Doc link. If you give the link to a friend, you both are viewing and modifying the exact same document online.

Code Example:

// Primitive behavior
let originalName = "John";
let copiedName = originalName;
copiedName = "Doe";
console.log(originalName); // "John" (unaffected)

// Reference behavior
let originalUser = { name: "Alice" };
let copiedUser = originalUser;
copiedUser.name = "Bob";
console.log(originalUser.name); // "Bob" (mutated via reference)
📋

Output:

"John"
"Bob"
📋

Common Mistakes:

Interview Follow-up Questions:

Interviewer: How can we check if a value is primitive or reference programmatically?

Candidate: We can use the typeof operator. If it returns "object" (excluding null) or "function", it is a reference type. Otherwise, it is primitive.

Quiz:

What is the output of console.log(typeof null) and why?

a) "null"
b) "undefined"
c) "object"

Answer: c) "object". This is a well-known historical bug in the original implementation of JavaScript where values were stored in 32-bit units, and the type tag for objects matched null's bitwise representation.

Key Takeaways:

🟢 Question 2: Easy

What is Hoisting?

Short Interview Answer:

Hoisting is the mechanism in JavaScript where variable and function declarations are moved to the top of their containing scope during the compilation phase, before execution begins.

Detailed Explanation:

Before executing any line of code, the JavaScript engine parses the entire script to register variables and functions. During this phase, memory is allocated. For variables declared with var, they are initialized to undefined. For functions declared with the function keyword, the entire body is saved in memory. This gives the illusion that declarations "float" to the top of the file.

Real Life Analogy:

A theater host checking the guest list before opening the doors. Even if your name is at the bottom of the printed registration sheet, they acknowledge you are on the list as soon as they scan the paper.

Code Example:

console.log(greet()); // "Hello!" works because functions are fully hoisted
console.log(score);   // undefined because only declaration is hoisted, not value

function greet() {
  return "Hello!";
}

var score = 100;
📋

Output:

"Hello!"
undefined
📋

Common Mistakes:

Interview Follow-up Questions:

Interviewer: Are variables declared with let and const hoisted?

Candidate: Yes, they are hoisted, but they are not initialized. They remain in the "Temporal Dead Zone" (TDZ) until the execution reaches the line where they are declared. Accessing them before that point throws a ReferenceError.

Quiz:

What is the output of the following block?

var x = 1;
function test() {
  console.log(x);
  var x = 2;
}
test();
📋

a) 1
b) undefined
c) ReferenceError

Answer: b) undefined. Because of local hosting, the local declaration var x inside test() is hoisted to the top of the function scope, shadowing the outer variable, but is initially initialized to undefined.

Key Takeaways:

🟢 Question 3: Easy

What is the Temporal Dead Zone (TDZ)?

Short Interview Answer:

The Temporal Dead Zone is the period/state between block entry and the line of declaration where variables declared with let and const cannot be accessed.

Detailed Explanation:

When JavaScript enters a block scope, variables defined with let and const are allocated in memory. However, they are protected with a status flags preventing read/write access. This zone of protection starts as soon as the block executes and lasts until the line where the variable declaration actually takes place is reached.

Real Life Analogy:

Reserving a table at a restaurant. The table is allocated for you, but you are not allowed to sit or eat at it until the reservation window officially starts.

Code Example:

{
  // TDZ for variable 'name' begins here
  // console.log(name); // Throws ReferenceError
  
  let name = "Developer"; // TDZ ends here
  console.log(name);      // Safe to access!
}
📋

Output:

"Developer"
📋

Common Mistakes:

Interview Follow-up Questions:

Interviewer: Does typeof safe-guard against the TDZ?

Candidate: No, typeof will throw a ReferenceError if called on a variable in the TDZ, whereas it simply returns "undefined" for variables that were never declared.

Quiz:

Which of the following will throw a ReferenceError?

a) let x; console.log(x);
b) console.log(y); let y = 10;
c) Both

Answer: b. Option a simply logs undefined because the variable has been initialized at execution time.

Key Takeaways:

🟢 Question 4: Easy

What is the difference between Scope and Lexical Environment?

Short Interview Answer:

Scope is the actual physical boundary where a variable is accessible. Lexical Environment is the internal structure containing local variables and a reference to its parent Lexical Environment.

Detailed Explanation:

Scope defines the visibility limits of identifiers. Lexical Environment is the mechanical concept JavaScript uses to achieve Scope. When a function executes, an execution context is pushed to the call stack. This context loads its own Lexical Environment which contains: 1. Environment Record (the actual variables stored here) 2. Outer Lexical Environment reference (where to search if a variable isn't found locally).

Real Life Analogy:

Scope is like a series of nesting Russian Dolls. Lexical environment is the physical physical plastic construct of each doll, allowing it to "fit" and "see" the boundaries of the doll enclosing it.

Code Example:

let globalValue = "Global";

function outer() {
  let outerValue = "Outer";
  
  function inner() {
    // Looks locally -> Outer -> Global
    console.log(outerValue, globalValue);
  }
  inner();
}
outer();
📋

Output:

"Outer" "Global"
📋

Interview Follow-up Questions:

Interviewer: When is the Lexical Environment determined?

Candidate: It is determined at compile-time (lexically), which means it depends on where the function was written in the source code, not where it is called.

Quiz:

What lexical scope system does JS use?

a) Dynamic Scope
b) Lexical (Static) Scope
c) Global scope only

Answer: b) Lexical Scope.

Key Takeaways:

🟢 Question 5: Easy

What is the difference between == and ===?

Short Interview Answer:

== (Loose Equality) checks for value equality and performs implicit type coercion. === (Strict Equality) checks for both value and type without coercion.

Detailed Explanation:

When comparing different types with loose equality (==), JS tries to reconcile their types first (coercion). For example, it converts strings and booleans to numbers prior to comparing. Strict equality (===) immediately returns false if the types differ.

Real Life Analogy:

Loose equality is like checking security based on name spelling match ignoring casing. Strict equality matches both name spelling and checks their passport type.

Code Example:

console.log(5 == "5");  // true (string "5" is coerced to number 5)
console.log(5 === "5"); // false (types do not match)
📋

Output:

true
false
📋

Interview Follow-up Questions:

Interviewer: What is the result of null == undefined and null === undefined?

Candidate: null == undefined is true (by specification exception), while null === undefined is false.

Quiz:

What is [] == false in JS?

a) true
b) false

Answer: a) true. Because empty array is coerced to an empty string, which is coerced to 0, matching false (coerced to 0).

Key Takeaways:

🟢 Question 6: Easy

What is the difference between Null and Undefined?

Short Interview Answer:

undefined means a variable has been declared but not yet assigned a value. null is an intentional assignment representing "no value" or an empty object reference.

Detailed Explanation:

JavaScript uses undefined as a default value placeholder. It is assigned automatically. null, on the other hand, is manually assigned by a developer to represent that the variable is intended to be completely empty at the moment.

Real Life Analogy:

An empty coffee cup: undefined means we haven't even decided if we are getting coffee or what goes into the cup. null means the cup was served deliberately empty.

Code Example:

let a;
let b = null;

console.log(a); // undefined
console.log(b); // null
📋

Output:

undefined
null
📋

Key Takeaways:

🟢 Question 7: Easy

What are Truthy and Falsy values?

Short Interview Answer:

A falsy value is a value that translates to false when evaluated in a boolean context. All other values are truthy.

Detailed Explanation:

There are exactly 8 falsy values in modern JS: false, 0, -0, 0n (BigInt zero), "" (empty string), null, undefined, and NaN. Absolutely everything else is truthy, including empty arrays [] and empty objects {}.

Code Example:

if ([]) {
  console.log("Empty array is Truthy!");
}
if ("") {
  // won't execute
} else {
  console.log("Empty string is Falsy!");
}
📋

Output:

"Empty array is Truthy!"
"Empty string is Falsy!"
📋

Key Takeaways:

🟢 Question 8: Easy

Explain pure vs impure functions.

Short Interview Answer:

A pure function always returns the exact same output for the same input and produces no side effects. An impure function can yield different outputs or modify external state.

Code Example:

// Pure
const add = (a, b) => a + b;

// Impure
let count = 0;
const increment = () => { count++; return count; };
📋

Key Takeaways:

🟢 Question 9: Easy

What is the difference between Shallow Copy and Deep Copy?

Short Interview Answer:

A shallow copy duplicates the top-level structure, keeping reference pointers to nested objects. A deep copy recursively clones every nested value and reference, decoupling them entirely.

Code Example:

const original = { a: 1, b: { c: 2 } };
const shallow = { ...original };
shallow.b.c = 99; // Alters original.b.c as well!

const deep = structuredClone(original);
deep.b.c = 1000; // Original remains unchanged
📋

Key Takeaways:

🟢 Question 10: Easy

Explain Object.freeze() vs const.

Short Interview Answer:

const prevents reassignment of a variable reference. Object.freeze() makes the properties of an object read-only and prevents adding or removing properties.

Code Example:

const user = { name: "John" };
user.name = "Alice"; // Works!

const frozenUser = Object.freeze({ name: "John" });
frozenUser.name = "Alice"; // Fails silently or throws error in strict mode
📋

Key Takeaways:

🟢 Question 11: Easy

What are JavaScript Template Literals?

Short Interview Answer:

Template literals are string literals delimited with backticks (`), allowing multi-line strings, string interpolation, and tagged templates.

Code Example:

const name = "Alice";
console.log(`Hello, ${name}!`);
📋

Key Takeaways:

🟢 Question 12: Easy

Explain Arrow Functions vs Regular Functions.

Short Interview Answer:

Arrow functions do not have their own this context (they inherit it lexically), do not have an arguments object, and cannot be used as constructors.

Code Example:

const obj = {
  name: "Bob",
  regular: function() { console.log(this.name); },
  arrow: () => { console.log(this.name); }
};
obj.regular(); // "Bob"
obj.arrow();   // undefined (or global/window object)
📋

Key Takeaways:

🟢 Question 13: Easy

What is Rest and Spread Operator?

Short Interview Answer:

The spread operator (...) unpacks items from an array/object. The rest operator collects multiple separate arguments or items into a single array structure.

Code Example:

// Spread
const arr = [1, 2];
const copy = [...arr, 3]; // [1, 2, 3]

// Rest
function sum(...nums) {
  return nums.reduce((acc, curr) => acc + curr, 0);
}
📋

Key Takeaways:

🟢 Question 14: Easy

What is Destructuring?

Short Interview Answer:

Destructuring is a clean syntax that allows unpacking properties from objects or values from arrays directly into individual variables.

Code Example:

const user = { id: 1, label: "Admin" };
const { label } = user;
console.log(label); // "Admin"
📋

Key Takeaways:

🟢 Question 15: Easy

What is the Map data structure vs standard Objects?

Short Interview Answer:

Map allows keys of any data type (including objects/functions) and maintains insertion order, whereas Object keys must be Strings or Symbols.

Code Example:

const myMap = new Map();
const keyObj = {};
myMap.set(keyObj, "Object Key Value");
console.log(myMap.get(keyObj));
📋

Key Takeaways:


Intermediate Mastery (Questions 16-35)

🟡 Question 16: Medium

What is a Closure?

Short Interview Answer:

A closure is the combination of a function bundled together with references to its surrounding state (the lexical environment). It lets an inner function access the outer scope even after the outer function has finished executing.

Detailed Explanation:

In JavaScript, every execution context has a reference to its lexical scope chain. When a function is declared, it "remembers" the scope environment in which it was born. If that function is returned or passed out of its parent wrapper, it carries this memory payload with it. Garbage collection cannot claim the parent variables because the active inner function maintains references to them.

Real Life Analogy:

A safe deposit box. The banker leaves (outer function completes), but your key (returned inner function) keeps access to the inner items because you still have the private relationship to that locker.

Code Example:

function createCounter() {
  let count = 0; // Private state
  return function() {
    count++;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
📋

Output:

1
2
📋

Interview Follow-up Questions:

Interviewer: What are closures used for in production?

Candidate: Data encapsulation/privacy, currying, function factories, memoization, and maintaining state in asynchronous environments like event listeners.

Quiz:

How many quizzes on closure? Let's trace this closure:

function outer() {
  let val = 10;
  return () => console.log(++val);
}
const fn = outer();
fn();
fn();
📋

a) 11 then 11
b) 11 then 12
c) 10 then 11

Answer: b) 11 then 12. The state is maintained across separate calls of the same returned inner function.

Key Takeaways:

🟡 Question 17: Medium

What is the Execution Context and Call Stack?

Short Interview Answer:

Execution Context is the environment in which code is evaluated and executed. The Call Stack is a LIFO (Last In, First Out) data structure used to manage execution contexts.

Detailed Explanation:

Whenever you start a JS application, the engine creates the Global Execution Context (GEC). When a function is called, a new Functional Execution Context (FEC) is created and pushed onto the Call Stack. Once completed, it is popped off.

Code Example:

function first() {
  second();
}
function second() {
  console.log("Running");
}
first();
📋

Key Takeaways:

🟡 Question 18: Medium

Explain JavaScript Prototypes and Prototype Chain.

Short Interview Answer:

A prototype is an object linked to every function/object in JS where properties and methods can be inherited. The Prototype Chain is the mechanism of traversal from child prototypes upward up to Object.prototype to resolve a property.

Code Example:

const animal = { eats: true };
const rabbit = Object.create(animal);
console.log(rabbit.eats); // true (inherited via Prototype Chain)
📋

Key Takeaways:

🟡 Question 19: Medium

What is the this keyword?

Short Interview Answer:

this refers to the object currently executing the function, evaluated entirely at execution runtime based on how the function was invoked.

Code Example:

function show() {
  console.log(this);
}
const obj = { method: show };
obj.method(); // 'this' points to 'obj'
show();       // 'this' points to Window/Global
📋

Key Takeaways:

🟡 Question 20: Medium

Explain call, apply, and bind.

Short Interview Answer:

call invokes a function immediately, specifying this and passing arguments individually. apply does the same but accepts arguments as an array. bind returns a new function with this locked, to be called later.

Code Example:

const user = { name: "John" };
function greet(prefix) { return `${prefix}, ${this.name}`; }

console.log(greet.call(user, "Hello")); // "Hello, John"
console.log(greet.apply(user, ["Hi"])); // "Hi, John"
const bound = greet.bind(user);
console.log(bound("Welcome"));         // "Welcome, John"
📋

Key Takeaways:

🟡 Question 21: Medium

What is a Promise?

Short Interview Answer:

A Promise is an object representing the eventual completion or failure of an asynchronous operation, existing in three states: Pending, Fulfilled, or Rejected.

Code Example:

const task = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Success!"), 100);
});
task.then(res => console.log(res));
📋

Key Takeaways:

🟡 Question 22: Medium

What is Async/Await?

Short Interview Answer:

Async/Await is syntactic sugar built on top of Promises. It allows writing asynchronous code that looks and behaves like synchronous sequential code.

Code Example:

async function getData() {
  const result = await fetch("https://api.example.com");
  return await result.json();
}
📋

Key Takeaways:

🟡 Question 23: Medium

What is the Event Loop?

Short Interview Answer:

The Event Loop is the runtime mechanism that continuously monitors the Call Stack and moves callbacks from the Callback and Microtask Queues to the stack when the stack is empty.

Detailed Explanation:

JavaScript is single-threaded, meaning it can only execute one thing at a time. Offloaded asynchronous actions are managed by browser Web APIs. When web tasks finish, their callbacks land in queue categories. The Event Loop waits for the Call Stack to hit zero and then checks the Microtask Queue first (for Promises) and then the Callback/Macrotask Queue (for timers) to push them on the stack for evaluation.

Real Life Analogy:

A restaurant dispatcher. Once a table is free (stack is empty), the dispatcher calls the next customer in line (the queues) to be seated.

Code Example:

console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise"));
console.log("End");
📋

Output:

"Start"
"End"
"Promise"
"Timeout"
📋

Key Takeaways:

🟡 Question 24: Medium

What is Event Delegation?

Short Interview Answer:

Event delegation is a design pattern where you attach a single event listener to a parent element instead of individual child nodes, leveraging event bubbling.

Code Example:

document.getElementById("parent-list").addEventListener("click", (e) => {
  if (e.target.tagName === "LI") {
    console.log("Clicked:", e.target.innerText);
  }
});
📋

Key Takeaways:

🟡 Question 25: Medium

What is Debouncing?

Short Interview Answer:

Debouncing limits the execution of a function until a specified idle duration has elapsed since its last invocation.

Code Example:

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

Key Takeaways:

🟡 Question 26: Medium

What is Throttling?

Short Interview Answer:

Throttling enforces a maximum frequency rate of execution, ensuring a function fires at most once per defined time window.

Code Example:

function throttle(func, limit) {
  let inThrottle;
  return function(...args) {
    if (!inThrottle) {
      func.apply(this, args);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  };
}
📋

Key Takeaways:

🟡 Question 27: Medium

Explain Event Bubbling vs Capturing.

Short Interview Answer:

Capturing (trickling) goes top-down from parent elements down to the target. Bubbling goes bottom-up, from the clicked child target up through parents to the global window root.

Code Example:

// Bubbling (default)
element.addEventListener("click", handler);

// Capturing (3rd param set to true)
element.addEventListener("click", handler, true);
📋

Key Takeaways:

🟡 Question 28: Medium

What are JavaScript Classes?

Short Interview Answer:

Classes are syntactic sugar built over JavaScript's existing prototype-based inheritance model, providing cleaner OOP structure.

Code Example:

class User {
  constructor(name) { this.name = name; }
  sayHi() { return `Hi, I am ${this.name}`; }
}
📋

Key Takeaways:

🟡 Question 29: Medium

What is ES6 Module System?

Short Interview Answer:

ES6 modules use import and export statements. They load statically, execute strictly, and help build decoupled tree-shakeable codebases.

Code Example:

// utils.js
export const log = (msg) => console.log(msg);

// main.js
import { log } from "./utils.js";
📋

Key Takeaways:

🟡 Question 30: Medium

Explain Set vs Array.

Short Interview Answer:

A Set is an unordered collection of unique values, while an Array is an ordered collection allowing duplicate values.

Code Example:

const values = new Set([1, 2, 2, 3]);
console.log(values); // Set { 1, 2, 3 }
📋

Key Takeaways:

🟡 Question 31: Medium

What is Currying?

Short Interview Answer:

Currying is a pattern where a function taking multiple arguments is transformed into a series of nested functions that take only one argument each.

Code Example:

const currySum = a => b => c => a + b + c;
console.log(currySum(1)(2)(3)); // 6
📋

Key Takeaways:

🟡 Question 32: Medium

What is Memoization?

Short Interview Answer:

Memoization is an optimization technique that caches the return values of expensive function computations based on their input parameters.

Code Example:

function memoize(fn) {
  const cache = {};
  return function(...args) {
    const key = JSON.stringify(args);
    if (key in cache) return cache[key];
    const result = fn.apply(this, args);
    cache[key] = result;
    return result;
  };
}
📋

Key Takeaways:

🟡 Question 33: Medium

What is a Polyfill?

Short Interview Answer:

A polyfill is fallback JS code used to provide modern feature support to older browser clients lacking that capability.

Code Example:

// Polyfill for Array.prototype.includes
if (!Array.prototype.includes) {
  Array.prototype.includes = function(searchElement) {
    return this.indexOf(searchElement) !== -1;
  };
}
📋

Key Takeaways:

🟡 Question 34: Medium

Explain Promises combinators: Promise.all vs Promise.allSettled.

Short Interview Answer:

Promise.all rejects immediately if any promise in the array fails. Promise.allSettled waits for all inputs to complete/fail and returns their status arrays.

Code Example:

const p1 = Promise.resolve(1);
const p2 = Promise.reject("error");

Promise.allSettled([p1, p2]).then(results => console.log(results));
📋

Key Takeaways:

🟡 Question 35: Medium

What is a Callback Function and Callback Hell?

Short Interview Answer:

A callback is a function passed as an argument to another function. Callback Hell is the term for deeply nested, unreadable callback structures that complicate control flow.

Code Example:

asyncOperation1(() => {
  asyncOperation2(() => {
    asyncOperation3(() => {
      // Callback hell nesting
    });
  });
});
📋

Key Takeaways:


Advanced & Runtime Mechanics (Questions 36-50)

🔴 Question 36: Hard

Explain Generators and Iterators.

Short Interview Answer:

Iterators are objects defining a standard next() output sequence structure. Generators are special functions that can pause/resume execution via the yield keyword, producing iterators under the hood.

Detailed Explanation:

Normal functions exit completely once they return. Generators (marked with function*) break this paradigm. They can yield execution mid-flow, returning progress states in the form { value, done }. The engine preserves the entire local frame state, ready to resume on the next execution request.

Code Example:

function* numberGenerator() {
  yield 1;
  yield 2;
}
const gen = numberGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: undefined, done: true }
📋

Output:

{ value: 1, done: false }
{ value: 2, done: false }
{ value: undefined, done: true }
📋

Interview Follow-up Questions:

Interviewer: Can we pass values back into a generator function programmatically?

Candidate: Yes, by passing a parameter into the next("value") call. It acts as the evaluated replacement of the paused yield expression inside the generator.

Key Takeaways:

🔴 Question 37: Hard

What is a Memory Leak and how to detect/fix it?

Short Interview Answer:

A memory leak occurs when items are no longer used by the application but remain allocated in the Heap because references to them are still active.

Code Example:

// Memory Leak: Unintentional global variable
function leaky() {
  leakedVar = new Array(1000000); // Assigned to window scope
}
📋

Key Takeaways:

🔴 Question 38: Hard

What is Garbage Collection?

Short Interview Answer:

Garbage Collection is an automated process in the JS engine that frees up memory occupied by objects that are no longer reachable from the root execution contexts.

Key Takeaways:

🔴 Question 39: Hard

Explain WeakMap and WeakSet.

Short Interview Answer:

WeakMap and WeakSet are collections that only accept objects/symbols as keys, maintaining "weak" references to those objects so they can be collected by Garbage Collection if no other references exist.

Code Example:

let cache = new WeakMap();
let obj = {};
cache.set(obj, "metadata");
obj = null; // Object is now eligible for GC, cleared from WeakMap automatically
📋

Key Takeaways:

🔴 Question 40: Hard

Explain Javascript Proxies.

Short Interview Answer:

A Proxy wraps an object, letting you intercept and customize fundamental operations like reading, writing, and modifying properties.

Code Example:

const target = { price: 100 };
const proxy = new Proxy(target, {
  get(target, prop) {
    return prop in target ? `$${target[prop]}` : "$0";
  }
});
console.log(proxy.price); // "$100"
📋

Key Takeaways:

🔴 Question 41: Hard

What is Reflect API?

Short Interview Answer:

Reflect is a built-in object providing methods to call interceptable JavaScript operations, mirroring proxy interceptors to simplify forwarding operations.

Code Example:

const user = { name: "Alice" };
console.log(Reflect.has(user, "name")); // true
📋

Key Takeaways:

🔴 Question 42: Hard

What are Web Workers?

Short Interview Answer:

Web Workers are browser APIs allowing JavaScript code to execute in background background threads, independent of the main user-interface thread.

Code Example:

// Main thread
const worker = new Worker("worker.js");
worker.postMessage("Start calculation");
worker.onmessage = (e) => console.log("Result:", e.data);
📋

Key Takeaways:

🔴 Question 43: Hard

Explain V8 Engine Pipeline compilation.

Short Interview Answer:

V8 parses JavaScript into an Abstract Syntax Tree (AST), compiles it to Bytecode via the 'Ignition' interpreter, and optimizes it using 'TurboFan' into fast machine code based on hot performance loops.

Key Takeaways:

🔴 Question 44: Hard

Write a Polyfill for Promise.all.

Short Interview Answer:

A custom function that returns a Promise, iterates through the array of promises, resolves each, and collects the results in a matching-index array. If any promise rejects, it rejects immediately.

Code Example:

function myPromiseAll(promises) {
  return new Promise((resolve, reject) => {
    let completed = 0;
    const results = [];
    if (promises.length === 0) return resolve(results);
    
    promises.forEach((p, idx) => {
      Promise.resolve(p)
        .then(val => {
          results[idx] = val;
          completed++;
          if (completed === promises.length) resolve(results);
        })
        .catch(reject);
    });
  });
}
📋

Key Takeaways:

🔴 Question 45: Hard

What is a Deep Copy polyfill?

Short Interview Answer:

A custom utility function that recursively copies all elements of objects and arrays, preserving depth and references while decoupling original entities.

Code Example:

function deepClone(obj) {
  if (obj === null || typeof obj !== "object") return obj;
  if (Array.isArray(obj)) {
    return obj.map(item => deepClone(item));
  }
  const clone = {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key]);
    }
  }
  return clone;
}
📋

Key Takeaways:

🔴 Question 46: Hard

Write a Custom Promise Polyfill.

Short Interview Answer:

A Class representing a custom Promise implementation that captures status, value, and callbacks, handling asynchronous execution flows manually.

Code Example:

class MyPromise {
  constructor(executor) {
    this.status = "pending";
    this.value = undefined;
    this.onResolved = [];
    
    const resolve = (val) => {
      if (this.status === "pending") {
        this.status = "fulfilled";
        this.value = val;
        this.onResolved.forEach(fn => fn(val));
      }
    };
    executor(resolve);
  }
  then(callback) {
    if (this.status === "fulfilled") {
      callback(this.value);
    } else {
      this.onResolved.push(callback);
    }
    return this;
  }
}
📋

Key Takeaways:

🔴 Question 47: Hard

Explain Tail Call Optimization.

Short Interview Answer:

Tail Call Optimization is a compiler mechanism where the engine avoids allocating a new stack frame if the last action of a function is a direct call returning another function.

Code Example:

function factorial(n, accum = 1) {
  if (n <= 1) return accum;
  return factorial(n - 1, n * accum); // Tail Call Position
}
📋

Key Takeaways:

🔴 Question 48: Hard

What is Symbol and its typical use-cases?

Short Interview Answer:

A Symbol is a unique and immutable primitive value, primarily used to create hidden, collision-free object property keys.

Code Example:

const hiddenId = Symbol("id");
const item = {
  [hiddenId]: 4022
};
console.log(item[hiddenId]); // 4022
📋

Key Takeaways:

🔴 Question 49: Hard

What is a Shadow DOM?

Short Interview Answer:

A Shadow DOM is a self-contained, encapsulated DOM tree detached from the main document DOM, preventing styles and structures from leaking in or out.

Code Example:

const host = document.querySelector("#shadow-host");
const shadowRoot = host.attachShadow({ mode: "open" });
shadowRoot.innerHTML = `<style>p { color: red; }</style><p>Shadow Boundary!</p>`;
📋

Key Takeaways:

🔴 Question 50: Hard

Advanced Interview Tricks & Edge Cases.

Short Interview Answer:

Tricks usually target unexpected behaviors like 0.1 + 0.2 !== 0.3 (floating-point binary representation), NaN !== NaN, and automatic semicolon insertion side-effects.

Code Example:

console.log(0.1 + 0.2 === 0.3); // false
console.log(Number.NaN === Number.NaN); // false
📋

Key Takeaways:


Final Revision Checklist


Senior Interview Strategy Tips

💡 Pro tip: Speak with execution visualization!
When an interviewer asks a code execution question, trace the flow verbally. Identify the Call Stack states, mention the Microtask Queue and Macrotask Queue explicitly, and demonstrate depth over memorized definitions. That approach instantly signals high capability to senior interviewers.

Related Resources