JavaScript interviews can be challenging, especially for mid-to-senior developers. They don’t just test your ability to write code-they test how well you understand the language, its quirks, and its execution model.

In this guide, we’ll cover real-world interview problems and tricky output-based questions that commonly appear in JavaScript interviews. Every example comes with explanations and working code.

Real JavaScript Interview Problems

1. Create Your Own map Function

Interviewers sometimes ask you to recreate native functions to see if you understand callbacks and array traversal.

 Array.prototype.myMap = function(callback) { const result = []; for (let i = 0; i < this.length; i++) { if (this.hasOwnProperty(i)) { result.push(callback(this[i], i, this)); } } return result; }; console.log([1, 2, 3].myMap(x => x * 2)); // [2, 4, 6] 

2. Implement Promise.all

This tests your grasp of asynchronous code.

 function promiseAll(promises) { return new Promise((resolve, reject) => { const results = []; let completed = 0; promises.forEach((promise, index) => { Promise.resolve(promise) .then(value => { results[index] = value; completed++; if (completed === promises.length) resolve(results); }) .catch(reject); }); }); } 

3. Run a Function Only Once

A simple closure-based problem to test state handling.

 function once(fn) { let executed = false; return function(...args) { if (!executed) { executed = true; return fn.apply(this, args); } }; } const init = once(() => console.log("Initialized")); init(); // Initialized init(); // (nothing happens) 

4. Flatten a Nested Array

This is a classic recursion problem.

 function flatten(arr) { let result = []; arr.forEach(item => { if (Array.isArray(item)) { result = result.concat(flatten(item)); } else { result.push(item); } }); return result; } console.log(flatten([1, [2, [3, 4]], 5])); // [1, 2, 3, 4, 5] 

5. Convert Object Keys to Camel Case

 function toCamel(obj) { const result = {}; for (let key in obj) { const camelKey = key.replace(/_([a-z])/g, (_, c) => c.toUpperCase()); result[camelKey] = obj[key]; } return result; } console.log(toCamel({ first_name: "John", last_name: "Doe" })); // { firstName: "John", lastName: "Doe" } 

Tricky JavaScript Output Questions

6. Hoisting Example

 console.log(a); var a = 10; 

Output: undefined
Explanation: Only the declaration is hoisted, not the value.

7. var vs let in Loops

 for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 1000); } // 3 3 3 
 for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 1000); } // 0 1 2 

let creates a new block-scoped variable for each iteration.

8. Closures

 function outer() { let x = 10; return function inner() { console.log(x); }; } const fn = outer(); fn(); // 10 

Even though outer has finished execution, inner remembers x.

9. Type Coercion

 console.log("5" + 1); // "51" console.log("5" - 1); // 4 

+ concatenates when a string is involved; – converts strings to numbers.

10. Array Comparison

 console.log([] == []); // false console.log([] === []); // false 

Arrays are compared by reference, not value.

11. Function Declarations vs Expressions

 foo(); // works function foo() { console.log("Hello"); } bar(); // TypeError var bar = function() { console.log("Hi"); }; 

Function declarations are hoisted; expressions are not.

12. Event Loop Behavior

 console.log("start"); setTimeout(() => console.log("timeout"), 0); Promise.resolve().then(() => console.log("promise")); console.log("end"); 

Output:

start
end
promise
timeout

Promises (microtasks) always run before setTimeout (macrotasks).

13. Object References

 let a = { value: 10 }; let b = a; b.value = 20; console.log(a.value); // 20 

Both a and b point to the same object in memory.