Interview Q&A / JavaScript
JavaScript interview questions
Closures, the event loop, this, promises and the core language questions every frontend round asks.
Prefer rapid revision? Practise JavaScript short interview answers →
- Why does a method lose its this when you pass it as a callback, and how do you fix it?
this is decided by how a function is called, not where it is defined. A detached method is called plainly, with no object before the dot, so this is lost. Fix it with bind, an arrow wrapper or an arrow class field.
IntermediateQuick answer1 min read - Why does await inside forEach not wait for each iteration?
forEach ignores the promises returned by an async callback, so it starts them all and moves on without waiting. Use for...of with await for sequential work, or Promise.all with map for parallel work.
IntermediateQuick answer1 min read - Why is 0.1 + 0.2 not equal to 0.3 in JavaScript?
Numbers are stored in binary floating point (IEEE 754), and 0.1 and 0.2 cannot be represented exactly in binary, so the sum is 0.30000000000000004. Compare with a small tolerance, or do money maths in whole paise.
IntermediateQuick answer1 min read - Write a function that deep clones an object, including nested arrays and circular references.
Return primitives as they are. For objects and arrays, create an empty copy, record it in a WeakMap so circular references reuse it, then recursively clone each property. In modern runtimes, structuredClone does this for you.
IntermediateQuick answerCoding1 min read - Write a function that flattens a nested array of any depth.
Loop through the array; if an item is an array, flatten it recursively and add its items, otherwise add the item. The built-in shortcut is arr.flat(Infinity).
IntermediateQuick answerCoding1 min read - Write a memoize function that caches the results of a pure function.
Wrap the function and store results in a Map keyed by its arguments. If the key exists, return the cached value; otherwise compute, store and return. It only works safely for pure functions.
IntermediateQuick answerCoding1 min read - Write a retry function with exponential backoff for an async call.
Loop up to a maximum number of attempts, awaiting the call in a try/catch. On failure, wait delay times 2 to the power of the attempt, then try again. After the last failure, throw the last error.
IntermediateQuick answerCoding1 min read - Write your own version of Function.prototype.bind.
Add a method on Function.prototype that remembers the original function, the chosen this and any preset arguments, and returns a new function that calls the original with apply, joining preset and new arguments.
IntermediateQuick answerCoding1 min read - Write your own version of Promise.all.
Return a new promise. Keep a results array and a counter. Wrap each input in Promise.resolve, store its value at its index, and resolve when the counter reaches zero. Reject as soon as any input rejects.
IntermediateQuick answerCoding1 min read - What is this after calling bind twice on the same function?
The first bind wins. A bound function's this is permanent, so calling bind again on it, or call and apply, cannot change it. Only extra preset arguments from the second bind take effect.
AdvancedQuick answer1 min read - Why does [] == ![] return true in JavaScript?
![] is false because an array is truthy. Then [] == false converts both sides to numbers: [] becomes "" then 0, and false becomes 0, so 0 == 0 is true.
AdvancedQuick answer1 min read