In this article
  1. Types and equality
  2. Functions and scope
  3. Objects and prototypes
  4. Asynchronous code
  5. Data handling
  6. Follow-up questions
  7. Sources

Types and equality

What are the data types in JavaScript, and why does typeof null return "object"?

JavaScript has seven primitive types, undefined, null, boolean, number, bigint, string and symbol, plus objects. The operator typeof null returns "object" because of a first-implementation detail: values were stored as a type tag and a value, and null shared the tag of objects (Mozilla Developer Network (MDN) Web Docs, typeof, May 2026). The result was kept for compatibility; test for null with === null, and for arrays with Array.isArray.

Why it is asked: it separates memorised trivia from knowing the quirk and the safe test. Read the full explanation: MDN Web Docs, typeof.

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

The === operator compares without converting types, so a number never equals a string. The == operator converts types first, so 0 == "0" is true while 0 === "0" is false, and null == undefined is true. Both treat NaN as unequal to itself; Object.is(NaN, NaN) is true (MDN Web Docs, equality, September 2026). Default to ===.

Why it is asked: it checks whether you know implicit conversion and its surprises. Read the full explanation: MDN Web Docs, equality comparisons.

Why does 0.1 + 0.2 not equal 0.3 in JavaScript?

JavaScript numbers are binary floating-point values, and binary cannot represent 0.1 exactly, so the sum is slightly off: it prints 0.30000000000000004. Compare with a tolerance instead of ===. MDN suggests testing whether the difference is below the machine-epsilon constant of the Number object, and warns that this suits only values near 1, so choose a tolerance to match your magnitude (MDN Web Docs, Number epsilon, July 2025).

Why it is asked: it tests whether you understand number representation, not only syntax. Read the full explanation: MDN Web Docs, Number epsilon.

Why does [] == false evaluate to true?

The loose equality operator converts both sides to primitives and then to numbers: the empty array becomes an empty string, then 0, and false becomes 0, so the comparison is true. Run in Node, [] == false is true, and 1 + "2" is the string "12" while "3" - 1 is the number 2. The fix is to use ===, and to convert values explicitly.

Why it is asked: it probes your model of implicit coercion. Read the full explanation: MDN Web Docs, equality comparisons.

Functions and scope

What is the difference between var, let and const?

The var keyword is function-scoped and reads as undefined before its line; let and const are block-scoped and throw a ReferenceError before their line, because they sit in the temporal dead zone from the start of the block until the declaration runs (MDN Web Docs, let, September 2026). A const forbids reassignment, not mutation: changing a property of a const object works, reassigning it throws a TypeError.

Why it is asked: scope and the dead zone are the base of most bug questions. Read the full explanation: MDN Web Docs, let.

What is hoisting?

Hoisting is the behaviour that declarations are known to the engine before the code in their scope runs. A function declaration is available with its body from the top of its scope, var starts as undefined, and a function expression assigned to a var is undefined until the assignment line. let and const are registered but unusable until their line, which is the temporal dead zone.

Why it is asked: it tests whether you can predict output without running the code. Read the full explanation: MDN Web Docs, Hoisting, June 2026.

What is a closure?

A closure is a function bundled with references to its surrounding state, its lexical environment (MDN Web Docs, Closures, November 2025). The function keeps access to those variables after the outer function has returned. A counter made by a function that returns an inner function shows it: the second call returns 2 because the inner function still holds the same variable.

Why it is asked: closures underlie callbacks, modules and private state. Read the full explanation: MDN Web Docs, Closures.

Why does a loop with var print 3, 3, 3 but a loop with let print 0, 1, 2?

A var loop variable is one variable shared by every closure, so each callback reads its final value, 3. A let loop variable is a new binding for each iteration, so each callback keeps its own value, 0, 1, 2. In Node, three functions pushed in a var loop returned [3, 3, 3], and in a let loop [0, 1, 2]. The older fix wrapped the body in an immediately invoked function.

Why it is asked: it is the standard closure trap. Read the full explanation: MDN Web Docs, Closures.

How is the value of this decided?

The value of this in a normal function depends on how the function is called, not where it is written: obj.f() sets it to obj, and a plain call sets it to undefined in strict mode or the global object otherwise. Arrow functions have no this of their own and use the one from where they were created, so call, apply and bind cannot change it (MDN Web Docs, this, May 2026).

Why it is asked: lost this is a common bug in callbacks and event handlers. Read the full explanation: MDN Web Docs, this.

What do call, apply and bind do?

All three set this for a function. The call method invokes the function now with arguments listed out, apply invokes it now with arguments in an array, and bind returns a new function with this fixed for later. In Node, a method detached from its object and rebound with bind({ n: "bound" }) returned "bound". They do not change an arrow function's this.

Why it is asked: it follows naturally from the this question. Read the full explanation: MDN Web Docs, this.

Knowing it is half the job. Saying it is the other half.

Interview Clozo is an AI interview copilot for real interview rounds: it hears the question and puts a strong answer on your screen, and you say it in your own words. See the features or how it works.

Start Free Trial →

Objects and prototypes

What is the prototype chain?

Every object has an internal link to another object, its prototype, and a property lookup follows the links until it finds the name or reaches null, which has no prototype and ends the chain (MDN Web Docs, prototype chain, November 2025). An object made with a prototype that holds c: 4 reads c as 4 although hasOwnProperty("c") is false.

Why it is asked: it tests whether you know how inheritance really works. Read the full explanation: MDN Web Docs, prototype chain.

Are JavaScript classes real classes?

JavaScript classes are built on prototypes, so they use the same object model, but they are not only syntax: MDN says classes "are built on prototypes but also have some syntax and semantics that are unique to classes" (MDN Web Docs, Classes, May 2026). typeof a class is "function", and its methods live on Class.prototype, so instances look methods up through the prototype chain. The unique parts, all confirmed in Node: calling a class without new throws a TypeError, a #private field is reachable only inside the class body and has no prototype equivalent, the class body is always strict, and class methods are non-enumerable.

Why it is asked: it separates syntax knowledge from how the language works. Read the full explanation: MDN Web Docs, Classes.

What is the difference between a shallow and a deep copy?

A shallow copy, such as { ...obj }, copies the top level and shares nested objects with the original. A deep copy duplicates the nested objects too, for example with structuredClone. In Node, after changing a nested value in the original, the spread copy showed the new value (2) and the structuredClone copy kept the old one (1). structuredClone throws a DataCloneError on a function, so objects holding functions need another approach (MDN Web Docs, structuredClone, October 2026).

Why it is asked: shared references are behind many state bugs. Read the full explanation: MDN Web Docs, deep copy and shallow copy.

Asynchronous code

How does the JavaScript event loop work?

The event loop runs one job at a time to completion. The agent takes a job from the queue, runs it until the stack is empty, then takes the next, and the microtask queue is drained before the next task is taken (MDN Web Docs, event loop, April 2026). So a promise callback runs before a zero-delay timer.

Why it is asked: it explains most ordering puzzles. Read the full explanation: MDN Web Docs, the event loop.

In what order does this code print?

setTimeout(() => console.log('timeout'), 0);
Promise.resolve().then(() => console.log('promise'));
queueMicrotask(() => console.log('microtask'));
console.log('sync');

Synchronous code prints first, then queued microtasks such as promise callbacks, then timer tasks. Node printed sync, promise, microtask, timeout. The two microtasks keep their registration order (the then was registered first), and the timer waits for the next task.

Microtasks run before the next timer taskFlow of three stages in the order Node printed them: synchronous code, then the microtask queue is drained, then one timer task runs.Synchronouscodeprints syncMicrotaskspromise,microtaskTimer taskprints timeoutDiagram: Interview Clozo, CC BY 4.0 ·interview.clozo.ai/blog/javascript-interview-questions.html
Synchronous code, then every microtask, then the next timer task: that is the order the example prints.CC BY 4.0 — source: JavaScript interview questions on types, closures, prototypes and the event loop
Text description of the diagram
  • Synchronous code prints first, then queued microtasks such as promise callbacks, then timer tasks.
  • The microtask queue is drained before the next task is taken.

Why it is asked: it is the standard output-prediction question. Read the full explanation: MDN Web Docs, the event loop.

What is a promise?

A promise is an object for the eventual result of an asynchronous operation. It starts pending and ends fulfilled, meaning the operation completed, or rejected, meaning it failed (MDN Web Docs, Promise, September 2026). Once settled it does not change. Handlers attached with then and catch run as microtasks, and chaining them lets one failure reach one catch.

Why it is asked: promises are the base of asynchronous code. Read the full explanation: MDN Web Docs, Promise.

How do Promise.all, allSettled, race and any differ?

The Promise.all method fulfils when every promise fulfils and rejects when any rejects. The allSettled method waits for all and reports each status. The race method settles with the first promise to settle, and any fulfils with the first to fulfil and rejects only when all reject (MDN Web Docs, Promise, September 2026). Use allSettled when partial results matter.

Why it is asked: it checks error-handling design for concurrent calls. Read the full explanation: MDN Web Docs, Promise.

What does async/await do under the hood?

An async function always returns a promise, and await pauses that function until a promise settles, letting other jobs run meanwhile. It is syntax over promises, not a second thread. In Node, an async function that returns 1 gave a value that was an instance of Promise. A rejected promise becomes a thrown error that try and catch can handle.

Why it is asked: it tests whether you know async code still runs on one thread. Read the full explanation: MDN Web Docs, async function.

Data handling

What is the difference between map, forEach and reduce?

The map method returns a new array of callback results and leaves the original unchanged (MDN Web Docs, Array map, July 2026). The forEach method returns undefined and exists for side effects. The reduce method folds an array into one value: summing [1, 2, 3] from 0 gives 6. Use map when you need the result and forEach when you do not.

Why it is asked: it checks fluent, side-effect-aware array handling. Read the full explanation: MDN Web Docs, Array map.

Why does [10, 9, 1].sort() return [1, 10, 9]?

The default sort compares elements as strings, so "10" comes before "9". In Node, [10, 9, 1].sort() returned [1, 10, 9] and sort((a, b) => a - b) returned [1, 9, 10]. Pass a comparison function for numbers. Note that sort changes the array in place (MDN Web Docs, Array sort, July 2025).

Why it is asked: it is a small trap that exposes careless defaults. Read the full explanation: MDN Web Docs, Array sort.

Follow-up questions

What are the common JavaScript interview questions?

The twenty above cover the ones that recur in search: types, equality, scope, closures, this, prototypes, the event loop, promises and array handling. For coding rounds, where you write the answer rather than explain it, practise the routine in the coding interview guide and see how the round fits the interview loop.

What JavaScript interview questions are asked for experienced developers?

Questions for people with several years of experience usually go deeper on the same topics: why the event loop orders output as it does, how a closure or this bug arises in a callback, how a prototype lookup works, and how to handle several promises at once. Be ready to explain a trade-off, such as Promise.all against allSettled, and not only the definition. For the design side of senior rounds, read the system design guide, and for framework-specific depth see React questions for experienced developers.

What does a JavaScript coding interview question look like?

Typically a short task: transform an array, predict the output of a snippet like the one above, or write a small function with a closure. Say your reasoning aloud, run the snippet in Node or a browser console when allowed, and test an edge case. The coding interview guide walks through that routine, and the behavioral interview guide covers the people side of the same loop.

Is JavaScript single-threaded?

The language runs one job at a time to completion on an agent, in MDN's description, which is why a long synchronous loop blocks everything else. Browsers and Node provide timers, network calls and worker threads around it.

Key takeaways
  • Use ===, and know typeof null is "object" and 0.1 + 0.2 is 0.30000000000000004.
  • let and const are block-scoped with a temporal dead zone; var is function-scoped.
  • A closure keeps its surrounding variables; this depends on how a function is called, except in arrow functions.
  • Lookups follow the prototype chain; classes are built on it but add semantics of their own.
  • Synchronous code runs first, then microtasks, then timers; async and await sit on promises.

Sources

  1. typeof (MDN Web Docs) — MDN Web Docs (Mozilla), 22 May 2026
  2. Number.EPSILON (MDN Web Docs) — MDN Web Docs (Mozilla), 10 Jul 2025
  3. Equality comparisons and sameness (MDN Web Docs) — MDN Web Docs (Mozilla), 27 Sep 2026
  4. let (MDN Web Docs) — MDN Web Docs (Mozilla), 4 Sep 2026
  5. Closures (MDN Web Docs) — MDN Web Docs (Mozilla), 4 Nov 2025
  6. this (MDN Web Docs) — MDN Web Docs (Mozilla), 22 May 2026
  7. Inheritance and the prototype chain (MDN Web Docs) — MDN Web Docs (Mozilla), 22 Nov 2025
  8. The event loop (MDN Web Docs) — MDN Web Docs (Mozilla), 6 Apr 2026
  9. Promise (MDN Web Docs) — MDN Web Docs (Mozilla), 14 Sep 2026
  10. Array.prototype.map() (MDN Web Docs) — MDN Web Docs (Mozilla), 12 Jul 2026
  11. Classes (MDN Web Docs) — MDN Web Docs (Mozilla), 22 May 2026
  12. Array.prototype.sort() (MDN Web Docs) — MDN Web Docs (Mozilla), 20 Jul 2025
  13. Hoisting (MDN Web Docs) — MDN Web Docs (Mozilla), 26 Jun 2026
  14. Deep copy (MDN Web Docs) — MDN Web Docs (Mozilla), 4 Sep 2026
  15. Shallow copy (MDN Web Docs) — MDN Web Docs (Mozilla), 4 Sep 2026
  16. structuredClone() (MDN Web Docs) — MDN Web Docs (Mozilla), 10 Oct 2026
  17. async function (MDN Web Docs) — MDN Web Docs (Mozilla), 8 Jul 2025