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.

