DEV Community

Cover image for 30 JavaScript Interview Questions for Developers (Explained Simply)
Akshay Kurve
Akshay Kurve

Posted on

30 JavaScript Interview Questions for Developers (Explained Simply)

JavaScript is everywhere.

From small websites to large-scale applications, JavaScript powers most of the modern web. Because of this, JavaScript interviews often focus on fundamentals rather than obscure tricks.

If you're preparing for a frontend, full-stack, or even backend (Node.js) role, you'll almost certainly encounter some of these questions.

This guide covers 30 common JavaScript interview questions with clear explanations and simple examples, so even beginners can understand them.


📊 JavaScript in 2026: Why It Still Matters

Before we dive in, here's why mastering JavaScript is more relevant than ever:

  • JavaScript remains the #1 most-used programming language — used by 66% of developers in the 2025 Stack Overflow Developer Survey, maintaining its top spot for over a decade.
  • 16.5 million developers worldwide use JavaScript as of 2024, making it the most widely used language globally.
  • TypeScript became the #1 language on GitHub for the first time in August 2025, surpassing Python with 2.6 million monthly contributors — and TypeScript is built on top of JavaScript.
  • Node.js remains the most popular runtime, used by 40.8% of developers.
  • JavaScript developer salaries in the US range from $87,500 to $171,600 annually, with Node.js specialists averaging $142,410/year.
  • The JavaScript ecosystem has stabilized — React, Vue, Svelte, and Angular are mature; the main battle has moved to meta-frameworks like Next.js and Astro, and build tools like Vite.
  • ECMAScript 2025 shipped with Iterator helpers, new Set methods, Promise.try, and JSON modules. ECMAScript 2026 (shipping June 2026) is expected to add the Temporal API, the using keyword for resource disposal, Math.sumPrecise(), and more.

Whether you're a beginner or a seasoned dev, JavaScript knowledge is a non-negotiable skill for web development careers.


📑 Table of Contents

Fundamentals

Functions & Syntax

Advanced Concepts

Browser & Storage

OOP & Type System

Modern JavaScript

Bonus


1. What is JavaScript?

⬆ Back to Top

JavaScript is a high-level, dynamic programming language used to create interactive web pages and applications.

It allows developers to:

  • Manipulate the webpage (DOM)
  • Respond to user actions (events)
  • Communicate with servers (AJAX, Fetch API)
  • Build full applications (frontend + backend)

JavaScript runs in:

Environment Example
Browsers Chrome, Firefox, Safari, Edge
Servers Node.js, Deno, Bun
Mobile apps React Native, Ionic
Desktop apps Electron (VS Code, Discord, Slack)

Example:

console.log("Hello World");
Enter fullscreen mode Exit fullscreen mode

Why interviewers ask this

They want to know if you understand JavaScript's role in the ecosystem — that it's not just a "front-end" language but a full-stack, multi-platform technology.

2026 Context

JavaScript was the programming language of choice for 62.3% of developers in 2024 and rose to 66% in 2025. It has been the most popular language in the Stack Overflow Developer Survey every year since the survey's inception in 2011. Despite Python's rapid growth driven by AI/ML, JavaScript remains essential for web development, and its ecosystem continues to expand with a 15% year-over-year spike in npm package consumption.


2. What are the different data types in JavaScript?

⬆ Back to Top

JavaScript has two main categories of data types.

Primitive Types (7 types)

These store single, immutable values.

Type Example Notes
string "hello" Text data
number 42, 3.14 Integers and floats
boolean true, false Logical values
null null Intentional empty value
undefined undefined Variable declared but not assigned
symbol Symbol("id") Unique identifier (ES2015)
bigint 123n Arbitrary precision integers (ES2020)
let name = "Alex";       // string
let age = 25;            // number
let isActive = true;     // boolean
let score = null;        // null
let address;             // undefined
let id = Symbol("id");   // symbol
let big = 9007199254740991n; // bigint
Enter fullscreen mode Exit fullscreen mode

Non-Primitive Types (Reference Types)

These store references to collections of values.

Type Example
Object { name: "Alex", age: 25 }
Array [1, 2, 3]
Function function greet() {}
Date new Date()
RegExp /pattern/g
Map / Set new Map(), new Set()
let user = {
  name: "Alex",
  age: 25
};

let scores = [95, 87, 92];

let greet = function() {
  return "Hello!";
};
Enter fullscreen mode Exit fullscreen mode

Key difference: Value vs. Reference

// Primitives — copied by value
let a = 10;
let b = a;
b = 20;
console.log(a); // 10 (unchanged)

// Objects — copied by reference
let obj1 = { name: "Alex" };
let obj2 = obj1;
obj2.name = "Sam";
console.log(obj1.name); // "Sam" (changed!)
Enter fullscreen mode Exit fullscreen mode

Common interview follow-up

"What is typeof null?"

typeof null // "object" — this is a well-known JavaScript bug from its earliest implementation
Enter fullscreen mode Exit fullscreen mode

3. What is the difference between var, let, and const?

⬆ Back to Top

This is one of the most common JavaScript interview questions.

Feature var let const
Scope Function Block Block
Redeclare ✅ Yes ❌ No ❌ No
Reassign ✅ Yes ✅ Yes ❌ No
Hoisting ✅ Yes (undefined) ✅ Yes (TDZ) ✅ Yes (TDZ)
Introduced ES1 (1997) ES6 (2015) ES6 (2015)

var

  • Function scoped
  • Can be redeclared
  • Hoisted and initialized as undefined
var x = 10;
var x = 20; // No error
console.log(x); // 20

function example() {
  var y = 5;
}
console.log(y); // ReferenceError — y is function scoped
Enter fullscreen mode Exit fullscreen mode

let

  • Block scoped
  • Cannot be redeclared in the same scope
  • Can be reassigned
  • Has a Temporal Dead Zone (TDZ)
let count = 10;
count = 20; // ✅ OK — reassignment

let count = 30; // ❌ SyntaxError — redeclaration

if (true) {
  let blockVar = "inside";
}
console.log(blockVar); // ReferenceError — block scoped
Enter fullscreen mode Exit fullscreen mode

const

  • Block scoped
  • Cannot be reassigned
  • Must be initialized at declaration
const PI = 3.14;
PI = 3.15; // ❌ TypeError — cannot reassign
Enter fullscreen mode Exit fullscreen mode

⚠️ Important: Objects declared with const can still be mutated

const user = { name: "Alex" };
user.name = "Sam";   // ✅ OK — mutation, not reassignment
user = {};            // ❌ TypeError — reassignment

// To prevent mutation, use Object.freeze()
const frozen = Object.freeze({ name: "Alex" });
frozen.name = "Sam";  // Silently fails (or throws in strict mode)
Enter fullscreen mode Exit fullscreen mode

Best Practice in 2026

const by default  let when you need to reassign  never use var
Enter fullscreen mode Exit fullscreen mode

4. What is hoisting in JavaScript?

⬆ Back to Top

Hoisting is JavaScript's behavior of moving variable and function declarations to the top of their scope during the compilation phase — before the code executes.

var hoisting

console.log(x); // undefined (not an error!)
var x = 5;
Enter fullscreen mode Exit fullscreen mode

Internally, the engine treats it as:

var x;           // declaration is hoisted
console.log(x);  // undefined
x = 5;           // assignment stays in place
Enter fullscreen mode Exit fullscreen mode

let/const hoisting (Temporal Dead Zone)

let and const are also hoisted, but they are not initialized. Accessing them before declaration throws a ReferenceError.

console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
Enter fullscreen mode Exit fullscreen mode

The period between entering the scope and the declaration is called the Temporal Dead Zone (TDZ).

Function hoisting

Function declarations are fully hoisted — both the name and the body:

greet(); // "Hello!" — works before declaration

function greet() {
  console.log("Hello!");
}
Enter fullscreen mode Exit fullscreen mode

Function expressions are NOT fully hoisted:

greet(); // TypeError: greet is not a function

var greet = function() {
  console.log("Hello!");
};
Enter fullscreen mode Exit fullscreen mode

Visual Summary

┌─────────────────────────────────────────┐
│            Hoisting Behavior            │
├──────────┬───────────┬──────────────────┤
│   var    │  Hoisted  │  Initialized as  │
│          │     ✅    │   undefined      │
├──────────┼───────────┼──────────────────┤
│   let    │  Hoisted  │  NOT initialized │
│          │     ✅    │   (TDZ error)    │
├──────────┼───────────┼──────────────────┤
│  const   │  Hoisted  │  NOT initialized │
│          │     ✅    │   (TDZ error)    │
├──────────┼───────────┼──────────────────┤
│ function │  Hoisted  │  Fully available │
│ decl.    │     ✅    │                  │
├──────────┼───────────┼──────────────────┤
│ function │  Hoisted  │  As var          │
│ expr.    │     ✅    │  (undefined)     │
└──────────┴───────────┴──────────────────┘
Enter fullscreen mode Exit fullscreen mode

5. What is a closure?

⬆ Back to Top

A closure happens when a function remembers and retains access to variables from its outer (lexical) scope, even after the outer function has finished executing.

Basic Example

function outer() {
  let count = 0;

  return function inner() {
    count++;
    console.log(count);
  };
}

const counter = outer();
counter(); // 1
counter(); // 2
counter(); // 3
Enter fullscreen mode Exit fullscreen mode

The inner function "closes over" the count variable. Even though outer() has finished, inner still has access to count.

Why closures matter

Closures are used everywhere in JavaScript:

Use Case Description
Data privacy Create private variables
Factory functions Generate specialized functions
Event handlers Remember state in callbacks
Memoization Cache expensive computations
Module pattern Encapsulate code

Practical Example: Data Privacy

function createBankAccount(initialBalance) {
  let balance = initialBalance; // private variable

  return {
    deposit(amount) {
      balance += amount;
      return balance;
    },
    withdraw(amount) {
      if (amount > balance) return "Insufficient funds";
      balance -= amount;
      return balance;
    },
    getBalance() {
      return balance;
    }
  };
}

const account = createBankAccount(100);
account.deposit(50);       // 150
account.withdraw(30);      // 120
account.getBalance();      // 120
console.log(account.balance); // undefined — balance is private!
Enter fullscreen mode Exit fullscreen mode

Common Interview Trap: Closures in Loops

// ❌ Bug: All log "3" because var is function-scoped
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Output: 3, 3, 3

// ✅ Fix 1: Use let (block-scoped)
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Output: 0, 1, 2

// ✅ Fix 2: Use IIFE to create a closure
for (var i = 0; i < 3; i++) {
  (function(j) {
    setTimeout(() => console.log(j), 100);
  })(i);
}
// Output: 0, 1, 2
Enter fullscreen mode Exit fullscreen mode

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

⬆ Back to Top

== (Loose Equality / Abstract Equality)

  • Compares values after type coercion
  • JavaScript converts types to make them match before comparing
5 == "5"       // true  (string "5" → number 5)
0 == false     // true  (false → 0)
null == undefined // true (special rule)
"" == 0        // true  ("" → 0)
Enter fullscreen mode Exit fullscreen mode

=== (Strict Equality / Identity)

  • Compares both value AND type
  • No type conversion
5 === "5"      // false (number ≠ string)
0 === false    // false (number ≠ boolean)
null === undefined // false (different types)
"" === 0       // false (string ≠ number)
Enter fullscreen mode Exit fullscreen mode

Type Coercion Table

Expression == ===
5 == "5" true false
0 == false true false
"" == false true false
null == undefined true false
NaN == NaN false false
[] == false true false

⚠️ The NaN gotcha

NaN === NaN  // false — NaN is never equal to anything, including itself!

// Use Number.isNaN() instead
Number.isNaN(NaN)  // true
Enter fullscreen mode Exit fullscreen mode

Best Practice

// Always use === and !== in production code
if (user.age === 25) { ... }
if (status !== "active") { ... }
Enter fullscreen mode Exit fullscreen mode

Most linters (ESLint eqeqeq rule) will flag == as a warning. Strict equality is the industry standard.


7. What is the DOM?

⬆ Back to Top

DOM stands for Document Object Model.

It represents the HTML page as a tree structure of nodes that JavaScript can read, modify, add to, and delete from.

HTML → DOM Tree

<html>
  <body>
    <h1>Hello</h1>
    <p>World</p>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode
document
  └── html
       └── body
            ├── h1
            │    └── "Hello"
            └── p
                 └── "World"
Enter fullscreen mode Exit fullscreen mode

Common DOM Methods

// Select elements
document.getElementById("app");
document.querySelector(".card");
document.querySelectorAll("li");

// Modify content
element.textContent = "New text";
element.innerHTML = "<strong>Bold</strong>";

// Modify styles
element.style.color = "red";
element.classList.add("active");
element.classList.toggle("hidden");

// Create & append
const div = document.createElement("div");
div.textContent = "I'm new!";
document.body.appendChild(div);

// Remove
element.remove();

// Attributes
element.setAttribute("data-id", "123");
element.getAttribute("href");
Enter fullscreen mode Exit fullscreen mode

Real-World Example

// Toggle dark mode
const toggleBtn = document.querySelector("#dark-mode-toggle");

toggleBtn.addEventListener("click", () => {
  document.body.classList.toggle("dark-mode");
  const isDark = document.body.classList.contains("dark-mode");
  toggleBtn.textContent = isDark ? "☀️ Light Mode" : "🌙 Dark Mode";
});
Enter fullscreen mode Exit fullscreen mode

Virtual DOM (Interview Bonus)

Modern frameworks like React use a Virtual DOM — an in-memory representation of the real DOM. When state changes, React:

  1. Creates a new Virtual DOM tree
  2. Diffs it against the previous one
  3. Applies only the minimal changes to the real DOM

This makes UI updates much faster than manipulating the real DOM directly.


8. What are arrow functions?

⬆ Back to Top

Arrow functions (introduced in ES6/2015) are a shorter syntax for writing functions — but they also behave differently in key ways.

Syntax Comparison

// Traditional function
function add(a, b) {
  return a + b;
}

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

// Single parameter — parentheses optional
const double = x => x * 2;

// No parameters — parentheses required
const greet = () => "Hello!";

// Multi-line — braces + explicit return
const calculate = (a, b) => {
  const sum = a + b;
  return sum * 2;
};
Enter fullscreen mode Exit fullscreen mode

Key Differences from Regular Functions

Feature Regular Function Arrow Function
this binding Own this Inherits from parent scope
arguments object ✅ Available ❌ Not available
Can be a constructor new Fn() ❌ Cannot use new
Has prototype ✅ Yes ❌ No
Hoisted ✅ If declared ❌ No (expression)

The this difference — most important

const user = {
  name: "Alex",

  // Regular function — `this` refers to user
  greetRegular: function() {
    console.log("Hello, " + this.name);
  },

  // Arrow function — `this` inherits from outer scope (NOT user)
  greetArrow: () => {
    console.log("Hello, " + this.name); // `this` is window/global
  }
};

user.greetRegular(); // "Hello, Alex" ✅
user.greetArrow();   // "Hello, undefined" ❌
Enter fullscreen mode Exit fullscreen mode

When to use what

✅ Use arrow functions for: callbacks, array methods, short functions
✅ Use regular functions for: object methods, constructors, when you need `this`
Enter fullscreen mode Exit fullscreen mode

9. What is an event in JavaScript?

⬆ Back to Top

An event is an action or occurrence that happens in the browser — triggered by the user, the browser, or by code.

Common Event Types

Category Events
Mouse click, dblclick, mouseenter, mouseleave, mousemove
Keyboard keydown, keyup, keypress
Form submit, change, input, focus, blur
Window load, resize, scroll, beforeunload
Touch touchstart, touchmove, touchend
Drag dragstart, dragover, drop

Adding Event Listeners

// Recommended approach
const button = document.querySelector("#myBtn");

button.addEventListener("click", (event) => {
  console.log("Button clicked!");
  console.log("Target:", event.target);
  console.log("Type:", event.type);
});

// With options
button.addEventListener("click", handler, {
  once: true,     // fires only once, then auto-removes
  capture: false, // bubbling phase (default)
  passive: true   // improves scroll performance
});
Enter fullscreen mode Exit fullscreen mode

Removing Event Listeners

function handleClick() {
  console.log("Clicked!");
}

button.addEventListener("click", handleClick);
button.removeEventListener("click", handleClick);
// Note: Must pass the SAME function reference
Enter fullscreen mode Exit fullscreen mode

The Event Object

document.addEventListener("keydown", (e) => {
  console.log(e.key);          // "Enter"
  console.log(e.code);         // "Enter"
  console.log(e.ctrlKey);      // true/false
  console.log(e.shiftKey);     // true/false
  e.preventDefault();          // Prevent default behavior
  e.stopPropagation();         // Stop event from bubbling
});
Enter fullscreen mode Exit fullscreen mode

10. What is event bubbling?

⬆ Back to Top

Event bubbling means that when an event occurs on an element, it propagates upward through its parent elements all the way to the document root.

How it works

Click on <button>

button → div → section → body → html → document
Enter fullscreen mode Exit fullscreen mode
<div id="parent">
  <button id="child">Click Me</button>
</div>
Enter fullscreen mode Exit fullscreen mode
document.getElementById("parent").addEventListener("click", () => {
  console.log("Parent clicked");
});

document.getElementById("child").addEventListener("click", () => {
  console.log("Child clicked");
});

// Click the button:
// Output:
// "Child clicked"
// "Parent clicked" ← bubbled up!
Enter fullscreen mode Exit fullscreen mode

Three phases of event propagation

1. Capturing Phase  →  document → html → body → div → button
2. Target Phase     →  button (the clicked element)
3. Bubbling Phase   →  button → div → body → html → document
Enter fullscreen mode Exit fullscreen mode

Stop bubbling

child.addEventListener("click", (e) => {
  e.stopPropagation(); // prevents parent from receiving the event
  console.log("Only child handles this");
});
Enter fullscreen mode Exit fullscreen mode

Event Delegation (Practical Use of Bubbling)

Instead of adding listeners to every child, use bubbling:

// ❌ Inefficient: listener on every <li>
document.querySelectorAll("li").forEach(li => {
  li.addEventListener("click", handleClick);
});

// ✅ Efficient: one listener on the parent
document.querySelector("ul").addEventListener("click", (e) => {
  if (e.target.tagName === "LI") {
    console.log("Clicked:", e.target.textContent);
  }
});
Enter fullscreen mode Exit fullscreen mode

Event delegation is a very common interview question and a best practice for dynamic lists.


11. What is this in JavaScript?

⬆ Back to Top

this refers to the object that is currently executing the function. Its value depends on how the function is called, not where it's defined.

this in different contexts

Context this refers to
Global scope (non-strict) window (browser) / global (Node.js)
Global scope (strict mode) undefined
Object method The object
Arrow function Inherited from enclosing scope
Event handler The element that received the event
Constructor (new) The new instance
call / apply / bind Whatever you pass

Examples

// 1. Object method
const user = {
  name: "John",
  greet() {
    console.log(this.name); // "John"
  }
};
user.greet();

// 2. Standalone function (non-strict)
function showThis() {
  console.log(this); // window (in browser)
}
showThis();

// 3. Arrow function — inherits `this`
const team = {
  name: "Engineering",
  members: ["Alice", "Bob"],
  listMembers() {
    this.members.forEach(member => {
      console.log(`${member} is on ${this.name}`);
      // Arrow function inherits `this` from listMembers
    });
  }
};
team.listMembers();

// 4. Explicit binding
function greet() {
  console.log(`Hello, ${this.name}`);
}
const person = { name: "Alex" };

greet.call(person);      // "Hello, Alex"
greet.apply(person);     // "Hello, Alex"
const bound = greet.bind(person);
bound();                 // "Hello, Alex"
Enter fullscreen mode Exit fullscreen mode

Common trap: lost this

const user = {
  name: "Alex",
  greet() {
    console.log(this.name);
  }
};

const fn = user.greet;
fn(); // undefined! — `this` is now window, not user

// Fix: use bind
const boundFn = user.greet.bind(user);
boundFn(); // "Alex"
Enter fullscreen mode Exit fullscreen mode

12. What is a Promise?

⬆ Back to Top

A Promise represents a value that may be available now, later, or never. It's JavaScript's way of handling asynchronous operations.

Three states

┌──────────┐     resolve()     ┌───────────┐
│ Pending  │ ──────────────→   │ Fulfilled │  (.then)
└──────────┘                   └───────────┘
      │
      │         reject()       ┌───────────┐
      └────────────────────→   │ Rejected  │  (.catch)
                               └───────────┘
Enter fullscreen mode Exit fullscreen mode

Creating a Promise

const promise = new Promise((resolve, reject) => {
  const success = true;

  if (success) {
    resolve("Data loaded successfully");
  } else {
    reject("Something went wrong");
  }
});
Enter fullscreen mode Exit fullscreen mode

Consuming a Promise

promise
  .then(data => console.log(data))    // "Data loaded successfully"
  .catch(error => console.error(error))
  .finally(() => console.log("Done")); // Always runs
Enter fullscreen mode Exit fullscreen mode

Real-World Example: Fetch API

fetch("https://api.example.com/users")
  .then(response => {
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return response.json();
  })
  .then(users => console.log(users))
  .catch(error => console.error("Failed:", error));
Enter fullscreen mode Exit fullscreen mode

Promise Utilities

// Wait for ALL to complete
Promise.all([fetchUsers(), fetchPosts(), fetchComments()])
  .then(([users, posts, comments]) => { ... });

// First to settle wins
Promise.race([fetchFromCDN1(), fetchFromCDN2()])
  .then(fastest => { ... });

// Wait for all to settle (ES2020)
Promise.allSettled([p1, p2, p3])
  .then(results => {
    results.forEach(r => {
      if (r.status === "fulfilled") console.log(r.value);
      if (r.status === "rejected") console.log(r.reason);
    });
  });

// First fulfilled (ES2021)
Promise.any([p1, p2, p3])
  .then(first => { ... });

// New in ES2025: Promise.try
Promise.try(() => {
  // Can be sync or async — always returns a Promise
  return maybeAsyncFunction();
});
Enter fullscreen mode Exit fullscreen mode

13. What is async/await?

⬆ Back to Top

async/await is syntactic sugar over Promises that makes asynchronous code look and behave like synchronous code.

Basic Syntax

async function getData() {
  try {
    const response = await fetch("https://api.example.com/data");

    if (!response.ok) {
      throw new Error(`HTTP Error: ${response.status}`);
    }

    const data = await response.json();
    console.log(data);
    return data;

  } catch (error) {
    console.error("Failed to fetch:", error.message);
  } finally {
    console.log("Fetch attempt complete");
  }
}
Enter fullscreen mode Exit fullscreen mode

Rules of async/await

  1. async functions always return a Promise
  2. await can only be used inside an async function (or at the top level of a module)
  3. await pauses execution until the Promise resolves

Sequential vs. Parallel

// ❌ Sequential — SLOW (waits for each one)
async function sequential() {
  const users = await fetchUsers();   // 2 sec
  const posts = await fetchPosts();   // 2 sec
  // Total: ~4 seconds
}

// ✅ Parallel — FAST (runs simultaneously)
async function parallel() {
  const [users, posts] = await Promise.all([
    fetchUsers(),   // 2 sec
    fetchPosts()    // 2 sec
  ]);
  // Total: ~2 seconds
}
Enter fullscreen mode Exit fullscreen mode

Top-Level Await (ES2022+)

In modules, you can now use await without wrapping in an async function:

// module.js
const config = await fetch("/config.json").then(r => r.json());
export default config;
Enter fullscreen mode Exit fullscreen mode

14. What is the event loop?

⬆ Back to Top

JavaScript is single-threaded, meaning it can only execute one thing at a time. But it can handle asynchronous operations using the event loop.

The Components

┌─────────────────────────────┐
│        Call Stack            │  ← Executes code, one function at a time
└─────────────┬───────────────┘
              │
              ▼
┌─────────────────────────────┐
│       Web APIs / Node APIs  │  ← setTimeout, fetch, DOM events (handled outside JS)
└─────────────┬───────────────┘
              │
              ▼
┌─────────────────────────────┐
│    Callback / Task Queue    │  ← setTimeout, setInterval callbacks
├─────────────────────────────┤
│    Microtask Queue          │  ← Promise .then(), queueMicrotask()
└─────────────┬───────────────┘
              │
              ▼
┌─────────────────────────────┐
│        Event Loop           │  ← Moves tasks from queues to call stack
└─────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

How it works

  1. Call stack executes synchronous code
  2. Async operations (setTimeout, fetch) are offloaded to Web APIs
  3. When complete, their callbacks are placed in the appropriate queue
  4. The event loop checks: "Is the call stack empty?" → If yes, move the next task from the queue to the stack
  5. Microtasks (Promises) always run before macrotasks (setTimeout)

Classic Interview Question

console.log("1");

setTimeout(() => console.log("2"), 0);

Promise.resolve().then(() => console.log("3"));

console.log("4");

// Output: 1, 4, 3, 2
// Why?
// 1 → synchronous
// 4 → synchronous
// 3 → microtask (Promise) — runs before macrotask
// 2 → macrotask (setTimeout) — runs last
Enter fullscreen mode Exit fullscreen mode

Priority Order

1. Synchronous code (call stack)
2. Microtasks (Promise callbacks, queueMicrotask)
3. Macrotasks (setTimeout, setInterval, I/O)
Enter fullscreen mode Exit fullscreen mode

15. What is a callback function?

⬆ Back to Top

A callback is a function passed as an argument to another function, to be executed later.

Basic Example

function greet(name, callback) {
  console.log("Hello " + name);
  callback();
}

function done() {
  console.log("Greeting complete");
}

greet("Alex", done);
// Output:
// "Hello Alex"
// "Greeting complete"
Enter fullscreen mode Exit fullscreen mode

Callbacks in the real world

// Array methods
[1, 2, 3].map(n => n * 2);           // [2, 4, 6]
[1, 2, 3].filter(n => n > 1);        // [2, 3]

// Event listeners
button.addEventListener("click", () => {
  console.log("Clicked!");
});

// setTimeout
setTimeout(() => {
  console.log("Delayed by 1 second");
}, 1000);

// Node.js style (error-first callbacks)
fs.readFile("data.txt", "utf-8", (err, data) => {
  if (err) return console.error(err);
  console.log(data);
});
Enter fullscreen mode Exit fullscreen mode

Callback Hell — the problem

// ❌ "Pyramid of doom"
getData(function(a) {
  getMoreData(a, function(b) {
    getEvenMoreData(b, function(c) {
      getFinalData(c, function(d) {
        console.log(d);
      });
    });
  });
});
Enter fullscreen mode Exit fullscreen mode

✅ The solution: Promises & async/await

// Clean and readable
async function fetchAll() {
  const a = await getData();
  const b = await getMoreData(a);
  const c = await getEvenMoreData(b);
  const d = await getFinalData(c);
  console.log(d);
}
Enter fullscreen mode Exit fullscreen mode

16. What is an IIFE?

⬆ Back to Top

IIFE stands for Immediately Invoked Function Expression — a function that runs as soon as it is defined.

Syntax

// Standard IIFE
(function() {
  console.log("Runs immediately");
})();

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

// With parameters
(function(name) {
  console.log("Hello, " + name);
})("Alex");

// Async IIFE
(async () => {
  const data = await fetch("/api/data");
  console.log(await data.json());
})();
Enter fullscreen mode Exit fullscreen mode

Why use IIFEs?

  1. Avoid polluting the global scope
  2. Create private variables
  3. Module pattern (before ES6 modules)
// Module pattern using IIFE
const CounterModule = (function() {
  let count = 0; // private

  return {
    increment() { return ++count; },
    decrement() { return --count; },
    getCount() { return count; }
  };
})();

CounterModule.increment(); // 1
CounterModule.increment(); // 2
CounterModule.getCount();  // 2
console.log(CounterModule.count); // undefined — private!
Enter fullscreen mode Exit fullscreen mode

Modern Alternative (ES Modules)

In 2026, most new code uses ES Modules instead of IIFEs for encapsulation. But IIFEs are still useful for one-off async execution and understanding legacy code.


17. What is destructuring?

⬆ Back to Top

Destructuring allows you to extract values from arrays or objects into individual variables — a concise, readable syntax introduced in ES6.

Object Destructuring

const user = {
  name: "Sam",
  age: 30,
  role: "Developer",
  address: {
    city: "NYC",
    zip: "10001"
  }
};

// Basic
const { name, age } = user;
console.log(name); // "Sam"

// Renaming
const { name: fullName } = user;
console.log(fullName); // "Sam"

// Default values
const { salary = 50000 } = user;
console.log(salary); // 50000

// Nested destructuring
const { address: { city } } = user;
console.log(city); // "NYC"

// Rest pattern
const { name: n, ...rest } = user;
console.log(rest); // { age: 30, role: "Developer", address: {...} }
Enter fullscreen mode Exit fullscreen mode

Array Destructuring

const colors = ["red", "green", "blue", "yellow"];

const [first, second] = colors;
console.log(first);  // "red"
console.log(second); // "green"

// Skip elements
const [, , third] = colors;
console.log(third); // "blue"

// Rest pattern
const [primary, ...others] = colors;
console.log(others); // ["green", "blue", "yellow"]

// Swap variables (no temp needed!)
let a = 1, b = 2;
[a, b] = [b, a];
console.log(a, b); // 2, 1
Enter fullscreen mode Exit fullscreen mode

Function Parameters

// Instead of:
function greet(user) {
  console.log(`Hello ${user.name}, age ${user.age}`);
}

// Destructure directly:
function greet({ name, age, role = "Guest" }) {
  console.log(`Hello ${name}, age ${age}, role: ${role}`);
}

greet({ name: "Alex", age: 25 });
// "Hello Alex, age 25, role: Guest"
Enter fullscreen mode Exit fullscreen mode

18. What is the spread operator?

⬆ Back to Top

The spread operator (...) expands (unpacks) elements of an iterable (array, object, string) into individual elements.

Arrays

// Combine arrays
const a = [1, 2];
const b = [3, 4];
const combined = [...a, ...b]; // [1, 2, 3, 4]

// Copy an array (shallow)
const original = [1, 2, 3];
const copy = [...original];

// Add elements
const withExtra = [0, ...original, 4]; // [0, 1, 2, 3, 4]

// Spread a string
const letters = [..."hello"]; // ["h", "e", "l", "l", "o"]
Enter fullscreen mode Exit fullscreen mode

Objects

// Merge objects
const defaults = { theme: "light", lang: "en" };
const userPrefs = { theme: "dark", fontSize: 16 };

const settings = { ...defaults, ...userPrefs };
// { theme: "dark", lang: "en", fontSize: 16 }
// Note: later values overwrite earlier ones
Enter fullscreen mode Exit fullscreen mode

Function Arguments

const numbers = [5, 2, 8, 1, 9];

Math.max(...numbers); // 9

// Instead of Math.max.apply(null, numbers)
Enter fullscreen mode Exit fullscreen mode

Spread vs. Rest: Same syntax, different purpose

// SPREAD: expands elements
const arr = [...otherArr, 4, 5];

// REST: collects elements
function sum(...numbers) {
  return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10
Enter fullscreen mode Exit fullscreen mode

19. What is the difference between map, filter, and reduce?

⬆ Back to Top

These are the three most important array methods for functional programming in JavaScript.

map — Transform each item

Returns a new array of the same length with each element transformed.

const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map(n => n * 2);
// [2, 4, 6, 8, 10]

const users = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 30 }
];

const names = users.map(user => user.name);
// ["Alice", "Bob"]
Enter fullscreen mode Exit fullscreen mode

filter — Select items based on condition

Returns a new array with only elements that pass the test.

const numbers = [1, 2, 3, 4, 5, 6, 7, 8];

const evens = numbers.filter(n => n % 2 === 0);
// [2, 4, 6, 8]

const adults = users.filter(user => user.age >= 18);
Enter fullscreen mode Exit fullscreen mode

reduce — Combine into a single value

Reduces an array to one accumulated result.

const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce((accumulator, current) => {
  return accumulator + current;
}, 0);
// 15

// Count occurrences
const fruits = ["apple", "banana", "apple", "cherry", "banana", "apple"];

const count = fruits.reduce((acc, fruit) => {
  acc[fruit] = (acc[fruit] || 0) + 1;
  return acc;
}, {});
// { apple: 3, banana: 2, cherry: 1 }
Enter fullscreen mode Exit fullscreen mode

Chaining them together

const orders = [
  { product: "Laptop", price: 999, shipped: true },
  { product: "Phone", price: 699, shipped: false },
  { product: "Tablet", price: 499, shipped: true },
  { product: "Watch", price: 299, shipped: true }
];

const shippedTotal = orders
  .filter(order => order.shipped)          // only shipped orders
  .map(order => order.price)               // extract prices
  .reduce((total, price) => total + price, 0); // sum them

console.log(shippedTotal); // 1797
Enter fullscreen mode Exit fullscreen mode

ES2025 Bonus: Iterator Helpers

ECMAScript 2025 added built-in Iterator helper methods (.map(), .filter(), .take(), .reduce(), .toArray()) directly on iterators, providing lazy evaluation for better performance with large datasets:

// ES2025 — lazy evaluation on iterators
function* numbers() {
  yield 1; yield 2; yield 3; yield 4;
}

const result = numbers()
  .map(x => x * 2)
  .filter(x => x > 4)
  .toArray();
// [6, 8] — lazily evaluated, element-by-element!
Enter fullscreen mode Exit fullscreen mode

This is one of the headline additions from ECMAScript 2025, providing functional operators with lazy evaluation on any iterable — not just arrays.


20. What is localStorage?

⬆ Back to Top

localStorage allows websites to store key-value data in the browser that persists even after the tab or browser is closed.

Basic Usage

// Store data
localStorage.setItem("username", "Alex");
localStorage.setItem("theme", "dark");

// Retrieve data
const name = localStorage.getItem("username"); // "Alex"

// Remove one item
localStorage.removeItem("username");

// Clear all localStorage
localStorage.clear();

// Check number of items
console.log(localStorage.length);
Enter fullscreen mode Exit fullscreen mode

Storing Objects (JSON)

localStorage only stores strings, so you must serialize objects:

// ❌ Wrong — stores "[object Object]"
localStorage.setItem("user", { name: "Alex" });

// ✅ Correct — serialize to JSON
const user = { name: "Alex", age: 25, theme: "dark" };
localStorage.setItem("user", JSON.stringify(user));

// Retrieve and parse
const stored = JSON.parse(localStorage.getItem("user"));
console.log(stored.name); // "Alex"
Enter fullscreen mode Exit fullscreen mode

Characteristics

Feature Value
Capacity ~5-10 MB per origin
Persistence Until manually cleared
Scope Per origin (protocol + domain + port)
Access Synchronous (blocks main thread)
Data type Strings only

⚠️ Security Note

Never store sensitive data (tokens, passwords, PII) in localStorage — it's accessible to any JavaScript running on the page (XSS vulnerability).


21. What is sessionStorage?

⬆ Back to Top

sessionStorage works exactly like localStorage but with one key difference: data is cleared when the browser tab is closed.

Comparison

Feature localStorage sessionStorage
Persistence Until cleared manually Until tab is closed
Shared across tabs ✅ Same origin ❌ Per tab
Capacity ~5-10 MB ~5-10 MB
API Same Same

Usage

// Same API as localStorage
sessionStorage.setItem("step", "3");
sessionStorage.getItem("step"); // "3"

// Close the tab → data is gone!
Enter fullscreen mode Exit fullscreen mode

When to use which

localStorage:   User preferences, themes, saved filters, non-sensitive settings
sessionStorage: Multi-step forms, temporary wizard state, one-time notifications
Neither:        Authentication tokens, passwords, sensitive data → use httpOnly cookies
Enter fullscreen mode Exit fullscreen mode

22. What is a prototype in JavaScript?

⬆ Back to Top

JavaScript uses prototype-based inheritance — objects can inherit properties and methods from other objects through the prototype chain.

How it works

Every JavaScript object has an internal link to another object called its prototype. When you access a property that doesn't exist on the object itself, JavaScript looks up the prototype chain.

const person = {
  greet() {
    console.log(`Hi, I'm ${this.name}`);
  }
};

const alex = Object.create(person);
alex.name = "Alex";

alex.greet(); // "Hi, I'm Alex" — found on prototype
Enter fullscreen mode Exit fullscreen mode

Constructor Functions & Prototypes

function Person(name) {
  this.name = name;
}

// Add methods to the prototype (shared across all instances)
Person.prototype.sayHello = function() {
  console.log(`Hello, I'm ${this.name}`);
};

const alice = new Person("Alice");
const bob = new Person("Bob");

alice.sayHello(); // "Hello, I'm Alice"
bob.sayHello();   // "Hello, I'm Bob"

// Both share the SAME method
console.log(alice.sayHello === bob.sayHello); // true
Enter fullscreen mode Exit fullscreen mode

Prototype Chain

alex → person → Object.prototype → null

alice → Person.prototype → Object.prototype → null
Enter fullscreen mode Exit fullscreen mode
console.log(alice.hasOwnProperty("name"));     // true — own property
console.log(alice.hasOwnProperty("sayHello")); // false — on prototype
console.log("sayHello" in alice);              // true — found in chain
Enter fullscreen mode Exit fullscreen mode

Modern Alternative: Classes (ES6)

class Person {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log(`Hello, I'm ${this.name}`);
  }
}

class Developer extends Person {
  constructor(name, language) {
    super(name);
    this.language = language;
  }

  code() {
    console.log(`${this.name} writes ${this.language}`);
  }
}

const dev = new Developer("Alex", "JavaScript");
dev.sayHello(); // "Hello, I'm Alex"
dev.code();     // "Alex writes JavaScript"
Enter fullscreen mode Exit fullscreen mode

⚠️ Classes are syntactic sugar over prototypes — under the hood, JavaScript still uses prototypal inheritance.


23. What is the difference between null and undefined?

⬆ Back to Top

undefined

A variable that has been declared but not assigned a value. It's JavaScript's default for "nothing here yet."

let x;
console.log(x);       // undefined

function greet() {}    // no return statement
console.log(greet());  // undefined

const user = { name: "Alex" };
console.log(user.age); // undefined — property doesn't exist
Enter fullscreen mode Exit fullscreen mode

null

An intentional, explicit assignment meaning "empty" or "no value." You set it deliberately.

let user = null; // explicitly set to "nothing"

// Common pattern: reset a value
let timer = setTimeout(() => {}, 1000);
clearTimeout(timer);
timer = null; // cleanup
Enter fullscreen mode Exit fullscreen mode

Comparison

Feature undefined null
Meaning Not assigned yet Intentionally empty
Type "undefined" "object" (bug)
Who sets it JavaScript (usually) Developer (explicitly)
In JSON Not valid Valid
Default parameter Triggers default Does NOT trigger default
typeof undefined  // "undefined"
typeof null       // "object" — famous JS bug

null == undefined   // true  (loose)
null === undefined  // false (strict)

null == 0          // false
undefined == 0     // false

// Default parameters
function greet(name = "Guest") {
  console.log(name);
}
greet(undefined); // "Guest" — triggers default
greet(null);      // null — does NOT trigger default
Enter fullscreen mode Exit fullscreen mode

Modern null-handling operators (very common in interviews)

// Nullish coalescing (??) — ES2020
const name = user.name ?? "Anonymous"; // only for null/undefined

// Optional chaining (?.) — ES2020
const city = user?.address?.city; // safe access, returns undefined if any part is null/undefined

// Logical assignment (??=) — ES2021
user.name ??= "Guest"; // assign only if null or undefined
Enter fullscreen mode Exit fullscreen mode

24. What are template literals?

⬆ Back to Top

Template literals (ES6) allow string interpolation, multi-line strings, and tagged templates using backticks (`).

String Interpolation

const name = "Alex";
const age = 25;

// Old way
const msg1 = "Hello, " + name + ". You are " + age + " years old.";

// Template literal
const msg2 = `Hello, ${name}. You are ${age} years old.`;

// Expressions inside ${}
const msg3 = `Next year you'll be ${age + 1}`;
const msg4 = `Status: ${age >= 18 ? "Adult" : "Minor"}`;
Enter fullscreen mode Exit fullscreen mode

Multi-Line Strings

// Old way
const html1 = "<div>\n" +
              "  <h1>Title</h1>\n" +
              "</div>";

// Template literal
const html2 = `
  <div>
    <h1>Title</h1>
    <p>Paragraph</p>
  </div>
`;
Enter fullscreen mode Exit fullscreen mode

Tagged Templates (Advanced)

function highlight(strings, ...values) {
  return strings.reduce((result, str, i) => {
    return result + str + (values[i] ? `<mark>${values[i]}</mark>` : "");
  }, "");
}

const name = "Alex";
const role = "developer";

const result = highlight`Hello, ${name}! You are a ${role}.`;
// "Hello, <mark>Alex</mark>! You are a <mark>developer</mark>."
Enter fullscreen mode Exit fullscreen mode

25. What is debouncing?

⬆ Back to Top

Debouncing delays the execution of a function until after a specified wait time has elapsed since the last invocation. If the function is called again before the wait ends, the timer resets.

Use Cases

  • Search input (wait for user to stop typing)
  • Window resize
  • Auto-save

Implementation

function debounce(fn, delay) {
  let timeoutId;

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

// Usage: Only call API after user stops typing for 300ms
const searchInput = document.querySelector("#search");

const handleSearch = debounce((event) => {
  console.log("Searching for:", event.target.value);
  // fetch(`/api/search?q=${event.target.value}`)
}, 300);

searchInput.addEventListener("input", handleSearch);
Enter fullscreen mode Exit fullscreen mode

Visual Timeline

User types:  H  e  l  l  o
             │  │  │  │  │
Timer:       ✘  ✘  ✘  ✘  │──300ms──▶ execute("Hello")
             (each keystroke resets the timer)
Enter fullscreen mode Exit fullscreen mode

26. What is throttling?

⬆ Back to Top

Throttling ensures a function runs at most once in a specified time interval, regardless of how many times it's triggered.

Use Cases

  • Scroll events
  • Mouse movement tracking
  • Rate limiting API calls
  • Game loop input handling

Implementation

function throttle(fn, limit) {
  let lastCall = 0;

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

// Usage: Track scroll position at most every 200ms
const handleScroll = throttle(() => {
  console.log("Scroll position:", window.scrollY);
}, 200);

window.addEventListener("scroll", handleScroll);
Enter fullscreen mode Exit fullscreen mode

Debounce vs. Throttle

Feature Debounce Throttle
When it fires After activity stops At regular intervals
Best for Search inputs, resize Scroll, mouse move
Frequency Once at the end Once per interval
Throttle (200ms):  ✅──200ms──✅──200ms──✅──200ms──✅
Debounce (200ms):  ✘──✘──✘──✘──✘──200ms──✅ (only fires once at the end)
Enter fullscreen mode Exit fullscreen mode

27. What are modules in JavaScript?

⬆ Back to Top

Modules allow code to be split into separate, reusable files with their own scope.

ES Modules (ESM) — The Standard in 2026

// math.js — Named exports
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
export const PI = 3.14159;

// Default export
export default function multiply(a, b) {
  return a * b;
}
Enter fullscreen mode Exit fullscreen mode
// app.js — Import
import multiply, { add, subtract, PI } from "./math.js";
import * as math from "./math.js"; // import everything

console.log(add(2, 3));       // 5
console.log(multiply(4, 5));  // 20
console.log(math.PI);         // 3.14159
Enter fullscreen mode Exit fullscreen mode

Dynamic Imports (Code Splitting)

// Load module only when needed
const button = document.querySelector("#loadChart");

button.addEventListener("click", async () => {
  const { renderChart } = await import("./chart.js");
  renderChart(data);
});
Enter fullscreen mode Exit fullscreen mode

JSON Modules (ES2025)

One of the new features in ECMAScript 2025 is direct JSON module imports:

import config from "./config.json" with { type: "json" };
console.log(config.apiUrl);
Enter fullscreen mode Exit fullscreen mode

ESM Adoption in 2026

2026 is widely considered the year of full ES Module adoption. Node.js now allows importing ESM from CJS code (backported to Node 20), meaning there's little reason to publish CommonJS anymore. Modern bundlers like Vite and Rolldown are ESM-first.


28. What is Node.js?

⬆ Back to Top

Node.js allows JavaScript to run outside the browser, on servers and anywhere else.

It's built on Chrome's V8 JavaScript engine and uses an event-driven, non-blocking I/O model.

What Node.js is used for

  • Backend APIs (REST, GraphQL)
  • Real-time applications (chat, collaboration)
  • Microservices
  • CLI tools
  • Serverless functions
  • Build tools (webpack, Vite, etc.)

Basic Example

// server.js
const http = require("http");

const server = http.createServer((req, res) => {
  res.writeHead(200, { "Content-Type": "application/json" });
  res.end(JSON.stringify({ message: "Hello from Node.js!" }));
});

server.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});
Enter fullscreen mode Exit fullscreen mode

Node.js Runtime Landscape in 2026

Node.js remains the most popular JavaScript runtime at 40.8% usage, though it has declined from its 2020 peak of 51%. Other runtimes are gaining ground:

Runtime Notes
Node.js Mature, massive ecosystem, 40.8% usage
Deno Secure by default, TypeScript-native, by Node.js creator
Bun Fastest runtime, all-in-one (runtime + bundler + test runner + pkg manager)

Node.js Developer Salaries (2026)

JavaScript-powered backend roles remain lucrative. According to 2026 Glassdoor data, the average Node.js developer salary in the US is $142,410/year, with senior roles averaging $167,179/year and top earners reaching $220,000+.


29. What is CORS?

⬆ Back to Top

CORS stands for Cross-Origin Resource Sharing — a browser security mechanism that controls which websites can access resources from another domain.

The Problem

Browsers enforce the Same-Origin Policy — by default, a web page can only request resources from the same origin (protocol + domain + port).

✅ https://myapp.com → https://myapp.com/api     (same origin)
❌ https://myapp.com → https://api.backend.com    (different origin)
❌ http://localhost:3000 → http://localhost:8080   (different port)
Enter fullscreen mode Exit fullscreen mode

How CORS Works

The server sends HTTP headers telling the browser which origins are allowed:

Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Enter fullscreen mode Exit fullscreen mode

Preflight Requests

For "complex" requests (PUT, DELETE, custom headers), the browser sends an OPTIONS preflight request first:

Browser → OPTIONS /api/users → Server
Server → 200 OK + CORS headers → Browser
Browser → Actual PUT /api/users → Server
Enter fullscreen mode Exit fullscreen mode

Common Server Setup (Express.js)

const cors = require("cors");

// Allow specific origin
app.use(cors({
  origin: "https://myapp.com",
  methods: ["GET", "POST", "PUT", "DELETE"],
  credentials: true
}));

// Or allow all (for development only!)
app.use(cors());
Enter fullscreen mode Exit fullscreen mode

Interview Tip

CORS errors happen in the browser, not on the server. The server responds fine — the browser blocks the response. This is why requests work in Postman but fail in the browser.


30. What is the difference between synchronous and asynchronous code?

⬆ Back to Top

Synchronous

Code runs line by line, in order. Each line must finish before the next one starts.

console.log("1. Start");
console.log("2. Processing...");
console.log("3. Done");

// Output: 1, 2, 3 (always in order)
Enter fullscreen mode Exit fullscreen mode

Asynchronous

Tasks that take time run in the background, and the rest of the code continues executing without waiting.

console.log("1. Start");

setTimeout(() => {
  console.log("2. This took time");
}, 1000);

console.log("3. End");

// Output: "1. Start", "3. End", "2. This took time"
Enter fullscreen mode Exit fullscreen mode

Real-World Analogy

Synchronous:  Order coffee → Wait 5 min → Get coffee → Order food → Wait 10 min → Get food
              Total: 15 minutes

Asynchronous: Order coffee → Order food → Get coffee (5 min) → Get food (10 min)
              Total: 10 minutes (parallel)
Enter fullscreen mode Exit fullscreen mode

Common Async Operations

Operation Method
API calls fetch(), axios
Timers setTimeout, setInterval
File I/O fs.readFile (Node.js)
Database queries Any DB driver
User input Event listeners

Three Async Patterns

// 1. Callbacks (old)
fetchData(function(result) {
  console.log(result);
});

// 2. Promises (better)
fetchData()
  .then(result => console.log(result))
  .catch(err => console.error(err));

// 3. Async/Await (best — modern standard)
async function main() {
  try {
    const result = await fetchData();
    console.log(result);
  } catch (err) {
    console.error(err);
  }
}
Enter fullscreen mode Exit fullscreen mode

Bonus: New JavaScript Features to Know in 2026

⬆ Back to Top

Interviewers increasingly expect knowledge of modern JavaScript features. Here's what's new or recently shipped:

ECMAScript 2025 (Finalized — June 2025)

Feature Description
Iterator Helpers .map(), .filter(), .take(), .reduce(), .toArray() directly on iterators with lazy evaluation
New Set Methods union(), intersection(), difference(), symmetricDifference(), isSubsetOf(), isSupersetOf()
Promise.try Wraps sync or async function in a Promise — streamlines error handling
JSON Modules import config from "./config.json" with { type: "json" }
RegExp.escape() Safely escape special characters in regex
Float16Array New typed array for half-precision floating point

ECMAScript 2026 (Draft — Ships June 2026)

Feature Description
Temporal API Replaces the broken Date object with immutable, timezone-aware date/time handling
using keyword Resource disposal — automatic cleanup when a variable goes out of scope
Math.sumPrecise() Precise floating-point addition for financial/scientific calculations
Intl.Locale enhancements Better internationalization (weekend info, writing direction, calendar variants)
Import Defer Deferred module execution for better performance
Array.fromAsync() Create arrays from async iterables
Base64/Hex encoding Uint8Array.fromBase64(), toBase64(), fromHex(), toHex()
Iterator.concat() Concatenate multiple iterators into one

Temporal API Example (Coming in 2026)

The Temporal API is the long-awaited replacement for JavaScript's notoriously broken Date object. It provides immutable, timezone-aware date/time handling and is already available in Chromium 144:

// Getting current date and time
const now = Temporal.Now.plainDateTimeISO();
console.log(now.toString()); // "2026-03-14T10:30:00"

// Create specific dates
const date = Temporal.PlainDate.from("2026-03-14");
const time = Temporal.PlainTime.from("14:30:00");

// Duration and arithmetic
const departure = Temporal.PlainDateTime.from("2026-03-14T08:00");
const arrival = Temporal.PlainDateTime.from("2026-03-14T16:30");
const duration = departure.until(arrival);
console.log(duration.toString()); // "PT8H30M"

// Timezone-aware
const meeting = Temporal.ZonedDateTime.from({
  timeZone: "America/New_York",
  year: 2026, month: 3, day: 14,
  hour: 14, minute: 0
});
Enter fullscreen mode Exit fullscreen mode

The using Keyword (ES2026)

A new way to manage resources that require cleanup — similar to using in C# or with in Python:

function manageResource() {
  using resource = new DatabaseConnection("my-db");
  // Use the resource here...
  // resource is automatically disposed when scope exits
  // No need for try/finally!
}
Enter fullscreen mode Exit fullscreen mode

TypeScript's Growing Dominance

It's worth noting that TypeScript has surpassed Python as the #1 language on GitHub by monthly contributors (2.6 million), and a 2025 study found 94% of errors generated by AI coding assistants are type-related — exactly the errors TypeScript catches. Learning TypeScript on top of JavaScript gives you a significant edge.


Interview Prep Strategy

⬆ Back to Top

Difficulty-Based Study Plan

🟢 Round 1: Fundamentals (Week 1-2)

Questions: 1, 2, 3, 6, 7, 8, 17, 18, 23, 24

Focus: Can you explain basic JavaScript concepts clearly?

🟡 Round 2: Core Concepts (Week 3-4)

Questions: 4, 5, 9, 10, 11, 15, 16, 19, 22, 27

Focus: Do you understand how JavaScript really works?

🔴 Round 3: Async & Advanced (Week 5-6)

Questions: 12, 13, 14, 20, 25, 26, 28, 29, 30

Focus: Can you build and debug real applications?

What Interviewers Actually Care About (2026)

Based on the latest developer surveys and hiring trends:

Skill Priority
Core JS fundamentals (closures, scope, this) 🔴 Must-know
Async patterns (Promises, async/await, event loop) 🔴 Must-know
DOM manipulation 🟡 Important for frontend
ES2020+ features (optional chaining, nullish coalescing) 🟡 Expected
TypeScript 🟡 Increasingly expected
ES2025/2026 features (Iterator helpers, Temporal) 🟢 Bonus points
AI tool awareness 🟢 Good to mention

According to the 2025 Stack Overflow Developer Survey, 69% of developers spent time learning a new coding skill or language in the last year, and 84% now use or plan to use AI tools in their development process. However, 46% don't trust the accuracy of AI tool output — so interviewers still deeply value developers who understand fundamentals.


Final Thoughts

⬆ Back to Top

JavaScript interviews in 2026 focus on core concepts rather than trick questions.

If you deeply understand:

  • ✅ Closures, scope, and hoisting
  • ✅ Promises, async/await, and the event loop
  • this binding and prototypal inheritance
  • ✅ DOM manipulation and event handling
  • ✅ Modern syntax (destructuring, spread, modules)

…you'll already be ahead of the majority of candidates.

The 2026 Reality

JavaScript is not going anywhere. Despite Python's growth in AI/ML, JavaScript remains the #1 most-used language across all developers, and the ecosystem has matured significantly — the framework wars have settled, build tools are consolidating around Vite and Rolldown, and TypeScript has become a near-default for serious projects.

The best way to prepare is to practice writing small programs and explaining concepts clearly, because interviewers often care more about how you think than memorized answers.

"TypeScript saved JavaScript from its own chaos."
— The developer community, every year since 2016
Enter fullscreen mode Exit fullscreen mode

If you found this useful, save it for your interview prep or share it with other developers preparing for JavaScript interviews.


Top comments (0)