Javascript Interview Questions

JavaScript Interview Questions - Core Concepts

40 interview questions on closures, the event loop, call stack, this keyword, execution context, prototypes, and scope.

By TechCoder TeamLast updated: 2026-06-02
In a Nutshell

40 interview questions on closures, the event loop, call stack, this keyword, execution context, prototypes, and scope. This interview-focused guide covers essential javascript interview questions - core concepts concepts for technical interviews.

JavaScript Interview Questions – Core Concepts

These 40 questions cover the intermediate concepts that separate junior from senior JavaScript developers: closures, the event loop, this binding, execution context, prototype-based inheritance, and scope mechanics.


1. What is a closure?

A closure is a function that retains access to its lexical scope even when executed outside that scope. It "remembers" the variables from where it was created.

function createCounter() {
    let count = 0;
    return function() { count++; return count; };
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2

[!TIP] Common use cases: Data privacy, function factories, memoization, module pattern, currying.

2. How does the event loop work?

The event loop is JavaScript's mechanism for handling asynchronous operations. It continuously checks the call stack and moves callbacks from queues to the stack when the stack is empty.

Call Stack → Web APIs → Callback/Task Queue → Event Loop → Call Stack
console.log("1");
setTimeout(() => console.log("2"), 0);
Promise.resolve().then(() => console.log("3"));
console.log("4");
// Output: 1, 4, 3, 2

3. What is the difference between microtasks and macrotasks?

TypeExamplesPriority
MicrotasksPromise.then/catch/finally, queueMicrotask, MutationObserverHigher
MacrotaskssetTimeout, setInterval, I/O, UI renderingLower

[!IMPORTANT] The event loop drains ALL microtasks before moving to the next macrotask. This is why 3 prints before 2 in the example above.

4. Explain this keyword behavior

The value of this depends on how a function is called, not where it's defined:

Contextthis refers to
Global (non-strict)window / globalThis
Global (strict mode)undefined
Object methodThe object calling the method
Constructor (new)The new instance being created
Arrow functionLexical this (from enclosing scope)
call() / apply() / bind()Explicitly set value
const obj = {
    name: "Alice",
    regular() { console.log(this.name); },   // "Alice"
    arrow: () => console.log(this.name)       // undefined
};

5. What is the call stack?

The call stack is a LIFO (Last In, First Out) data structure that tracks function execution. Each function call creates a stack frame; each return removes one. A stack overflow happens when too many frames accumulate (e.g., infinite recursion).

6. What is the execution context?

An execution context is the environment in which JavaScript code is evaluated and executed. It has two phases:

  1. Creation Phase: Scope chain, this binding, hoisted declarations
  2. Execution Phase: Assigns values, executes code line by line

Three types: Global, Function, and Eval execution contexts.

7. What is the prototype chain?

Every JavaScript object has an internal [[Prototype]] link (__proto__). When accessing a property, JS walks up this chain until it finds the property or reaches null.

const arr = [1, 2, 3];
// arr -> Array.prototype -> Object.prototype -> null

8. What's the difference between prototypal and classical inheritance?

  • Classical (Java, C++): Classes are blueprints; objects are instances. Inheritance copies behavior.
  • Prototypal (JavaScript): Objects inherit directly from objects via the prototype chain. No copying — delegation.

[!TIP] ES6 class syntax is syntactic sugar over JavaScript's prototypal inheritance.

9. What is the difference between call, apply, and bind?

  • call(thisArg, arg1, arg2, ...) — invokes immediately
  • apply(thisArg, [args]) — invokes immediately with array arg
  • bind(thisArg, arg1, ...) — returns a new bound function, does NOT invoke

10. What is the module pattern?

Uses closures to create private variables and expose a public API. The classic pattern before ES6 modules.

const counter = (function() {
    let count = 0;
    return {
        increment: () => ++count,
        getCount: () => count
    };
})();

11. What is currying?

Transforms a function with multiple arguments into a sequence of functions each taking a single argument.

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

12. What is memoization?

Caches function results to avoid redundant computations.

function memoize(fn) {
    const cache = new Map();
    return (...args) => {
        const key = JSON.stringify(args);
        if (!cache.has(key)) cache.set(key, fn(...args));
        return cache.get(key);
    };
}

13. What is debouncing?

Ensures a function is only called after a specified delay since the last invocation. Used for search inputs, resize handlers.

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

14. What is throttling?

Ensures a function is called at most once in a specified time period. Used for scroll events, button clicks.

15. What is an IIFE?

An Immediately Invoked Function Expression executes as soon as it's defined. Creates a private scope.

(function() { console.log("Runs immediately!"); })();

16. What is the difference between Function Declaration and Function Expression?

  • Declaration: function foo() {} — hoisted, can be called before definition
  • Expression: const foo = function() {} — not hoisted, TDZ applies with let/const

17. What are first-class functions?

In JavaScript, functions are first-class citizens — they can be assigned to variables, passed as arguments, returned from other functions, and stored in data structures.

18. What is a higher-order function?

A function that takes another function as an argument or returns a function.

[1, 2, 3].map(x => x * 2);  // Takes a function
function multiplyBy(n) { return x => x * n; } // Returns a function

19. What is a pure function?

A function that: (1) returns the same output for the same input, (2) has no side effects. Pure functions are predictable, testable, and cacheable.

20. What is a side effect?

Any operation that modifies state outside the function scope — modifying global variables, DOM manipulation, API calls, console.log, writing to files.

21. What is function composition?

Combines multiple functions where the output of one becomes the input of the next.

const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);

22. What is a generator function?

A function that can pause and resume execution using yield.

function* gen() { yield 1; yield 2; yield 3; }
const g = gen();
console.log(g.next().value); // 1

23. What is new keyword doing?

  1. Creates an empty object
  2. Sets this to the new object
  3. Links the object's [[Prototype]] to the constructor's prototype
  4. Executes the constructor function
  5. Returns the new object (unless constructor returns a non-primitive)

24. What is the difference between Object.create() and new?

  • new Constructor() — calls the constructor function, sets up prototype chain
  • Object.create(proto) — creates an object with specified prototype, no constructor call

25. What is the arguments object?

An array-like object accessible inside functions that contains all passed arguments. NOT available in arrow functions.

[!NOTE] In modern JS, rest parameters (...args) are preferred over arguments.

26. What are default parameters?

ES6 feature that sets default values for function parameters when undefined is passed.

function greet(name = "Guest") { return `Hello, ${name}`; }

27. What is a callback function?

A function passed as an argument to another function, to be executed later (synchronously or asynchronously).

28. What is "callback hell"?

Deeply nested callbacks that become unreadable. Solved by Promises and async/await.

29. What is recursion?

A function that calls itself. Must have a base case to prevent infinite recursion.

function factorial(n) { return n <= 1 ? 1 : n * factorial(n - 1); }

30. What is tail call optimization (TCO)?

An optimization where the compiler can reuse the current stack frame for tail-recursive calls. Supported in strict mode ES6+ but limited browser support.

31. What is an arrow function's this binding?

Arrow functions do NOT have their own this. They inherit this from the enclosing lexical scope. This binding cannot be changed with call, apply, or bind.

32. What does Function.prototype.bind() return?

A new function with this permanently bound and optional pre-filled arguments. The bound function cannot be re-bound.

33. What is the difference between slice() and splice()?

  • slice(start, end) — returns a shallow copy (does NOT mutate)
  • splice(start, deleteCount, ...items) — modifies the array in place

34. What is array destructuring?

Extracts values from arrays into variables.

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

35. What is object destructuring?

Extracts properties from objects into variables.

const { name, age = 25 } = { name: "Alice" };

36. What is the spread operator in objects?

Creates a shallow copy of an object's enumerable own properties.

const copy = { ...original };
const merged = { ...defaults, ...overrides };

37. What is optional chaining (?.)?

Safely accesses nested properties without checking each level.

const city = user?.address?.city; // undefined instead of error

38. What is nullish coalescing (??)?

Returns right operand only when left is null or undefined (not 0 or "").

const count = 0 ?? 10; // 0
const name = null ?? "Guest"; // "Guest"

39. What is the typeof operator limitation for arrays?

typeof [] returns "object". Use Array.isArray([]) to check for arrays.

40. What is instanceof used for?

Tests if an object's prototype chain contains a constructor's prototype.

console.log([] instanceof Array);  // true
console.log({} instanceof Object); // true