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 →
- What is the scope chain and how does JavaScript look up a variable?
The scope chain is the list of scopes from the current one outward to global. When you use a name, the engine checks the innermost scope first and moves outward until it finds it, or throws a ReferenceError.
BeginnerQuick answer1 min read - When would you use filter, find, some and every on an array?
filter returns all matches as an array, find returns the first match or undefined, some says whether at least one matches, and every says whether all match. some and every stop as soon as the answer is known.
BeginnerQuick answer1 min read - Why does "5" + 3 give "53" but "5" - 3 give 2?
The + operator does string concatenation if either side is a string, so 3 becomes "3". The -, * and / operators only work on numbers, so they convert "5" to 5 first.
BeginnerQuick answer1 min read - Why does [10, 9, 1].sort() give [1, 10, 9], and how do you sort numbers correctly?
By default sort converts items to strings and compares them in dictionary order, so "10" comes before "9". Pass a comparator like (a, b) => a - b to sort numbers. Note that sort changes the original array.
BeginnerQuick answer1 min read - Why does typeof null return "object" in JavaScript?
It is a bug from the first version of JavaScript: values carried a type tag, and null used the same tag as objects. Fixing it would break old websites, so it stays. Check for null with value === null.
BeginnerQuick answer1 min read - Write a function once(fn) that lets fn run only the first time it is called.
Return a wrapper that keeps a called flag and the first result in a closure. On the first call, run fn and store the result; on later calls, return the stored result without running fn.
BeginnerQuick answerCoding1 min read - Write a function that returns the first non-repeating character in a string.
Count how many times each character appears using a Map in one pass, then scan the string a second time and return the first character whose count is 1. Return null if none exists.
BeginnerQuick answerCoding1 min read - Write a function to reverse a string and use it to check for a palindrome.
Split the string into characters, reverse the array and join it back. A palindrome reads the same both ways, so clean the text (lowercase, letters and digits only) and compare it with its reverse.
BeginnerQuick answerCoding1 min read - How can awaiting inside a loop make code slow, and how do you run async tasks in parallel?
Each await pauses until that task finishes, so awaiting one after another runs them in sequence. Start all the promises first and await them together with Promise.all to run them in parallel.
IntermediateQuick answer1 min read - How can you create private variables in JavaScript using closures?
Declare the variable inside a function and return only functions that use it. The variable lives on in the closure, but no outside code can read or change it directly.
IntermediateQuick answer1 min read - How do you handle errors with async/await, and why can try/catch miss some of them?
Wrap await calls in try/catch. The catch only sees rejections that are awaited inside the try. A promise you forget to await, or return without awaiting, escapes the block.
IntermediateQuick answer1 min read - How does promise chaining work, and what happens after a catch?
Every then returns a new promise, resolved with whatever the handler returns, so calls chain. A thrown error skips later then handlers until a catch, and after a catch that returns a value, the chain continues normally.
IntermediateQuick answer1 min read - How does this behave inside an arrow function?
An arrow function has no this of its own. It uses the this of the surrounding code where it was written, and call, apply and bind cannot change it.
IntermediateQuick answer1 min read - How is Object.is different from the === operator?
Object.is works like === with two differences: Object.is(NaN, NaN) is true, and Object.is(0, -0) is false. React uses it to compare state values.
IntermediateQuick answer1 min read - What do [] + [] and [] + {} evaluate to in JavaScript?
[] + [] is the empty string and [] + {} is "[object Object]". The + operator turns both sides into strings when neither is a number, and an empty array stringifies to an empty string.
IntermediateQuick answer1 min read - What is BigInt in JavaScript and when would you use it?
BigInt is a primitive for whole numbers of any size, written with an n suffix like 123n. Use it when values pass Number.MAX_SAFE_INTEGER (2^53 - 1), such as large IDs. It cannot be mixed with regular numbers.
IntermediateQuick answer1 min read - What is method borrowing, and how do call and apply let you do it?
Method borrowing means using a method from one object on another by passing the other as this with call or apply. A classic case is Array.prototype.slice.call(arguments) on an array-like object.
IntermediateQuick answer1 min read - What is the difference between Object.freeze, Object.seal and Object.preventExtensions?
preventExtensions blocks adding properties. seal also blocks deleting and reconfiguring, but allows changing values. freeze blocks everything, so values are read-only too. All three are shallow.
IntermediateQuick answer1 min read - What is the difference between Promise.all, allSettled, race and any?
all waits for every promise and rejects on the first failure. allSettled waits for all and reports each outcome. race settles with the first promise to settle. any fulfills with the first success and rejects only if all fail.
IntermediateQuick answer1 min read - What is this inside a plain function call in strict mode versus sloppy mode?
In sloppy mode a plain call gets the global object as this. In strict mode it gets undefined. Strict mode also stops call from boxing a primitive this into an object.
IntermediateQuick answer1 min read - Which array methods change the original array and which return a new one?
push, pop, shift, unshift, splice, sort, reverse and fill change the original. map, filter, slice, concat, flat and the newer toSorted, toReversed and toSpliced return new arrays.
IntermediateQuick answer1 min read - Why does ['1', '2', '3'].map(parseInt) not give [1, 2, 3]?
map passes three arguments to the callback: item, index and array. parseInt uses the second as the radix, so it runs parseInt('2', 1) and parseInt('3', 2), both NaN. Use map(Number) or map(s => parseInt(s, 10)).
IntermediateQuick answer1 min read - 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