This is Part 8 of 9, a bonus practice article with 30 code-output challenges. Each challenge asks you to predict the result before revealing the answer and reasoning.
Complete series
This Dev.to series has five core handbook articles plus four focused practice extras. Open the series page to move through the complete reading order:
Part 1: JavaScript — core handbook, questions 1–120
Part 2: React — core handbook, questions 121–220
Part 3: React Native — core handbook, questions 221–420
Part 4: Performance & Architecture — core handbook, questions 421–560
Part 5: Senior & System Design — core handbook, questions 561–719
Part 6: Output-Based JavaScript Practice — bonus practice article
Part 7: Coding Interview Practice — bonus practice article
Part 8: Code Output Challenges — bonus practice article
Part 9: Current React Native Interview Questions — new high-frequency practice article
How to use this challenge set
Read the code, state the exact output or error, then explain the language rule. Do not run the snippet until you have committed to an answer. For React Native interviews, connect the JavaScript behavior to rendering, state updates, list handling, or the JavaScript thread when relevant.
Skills tested
- Hoisting, scope, closures, and
this
- Arrays, conditions, references, and object behavior
- Promises, timers,
async/await, and microtasks - Common JavaScript patterns used in React and React Native interviews
Code output challenges
Challenge 1. Block-scoped counter
Predict the exact output before opening the answer.
let total = 0;
for (let i = 0; i < 3; i++) {
total += i;
}
console.log(total);
Answer and explanation
Expected output: 3
Why: The loop adds 0, 1, and 2.
Challenge 2. var callback loop
Predict the exact output before opening the answer.
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
}, 0);
}
Answer and explanation
Expected output: 3, 3, 3
Why: var creates one shared function-scoped binding.
Challenge 3. let callback loop
Predict the exact output before opening the answer.
for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
}, 0);
}
Answer and explanation
Expected output: 0, 1, 2
Why: let creates a fresh binding for each iteration.
Challenge 4. Mutation through an array reference
Predict the exact output before opening the answer.
const a = [1, 2];
const b = a;
b.push(3);
console.log(a.length);
Answer and explanation
Expected output: 3
Why: a and b reference the same array.
Challenge 5. Shallow object copy
Predict the exact output before opening the answer.
const a = { user: { name: 'A' } };
const b = { ...a };
b.user.name = 'B';
console.log(a.user.name);
Answer and explanation
Expected output: B
Why: Object spread copies only the outer object.
Challenge 6. Array map with a missing return
Predict the exact output before opening the answer.
console.log(
[1, 2].map((x) => {
x * 2;
}),
);
Answer and explanation
Expected output: [undefined, undefined]
Why: A block-bodied arrow function needs an explicit return.
Challenge 7. reduce accumulator
Predict the exact output before opening the answer.
console.log([1, 2, 3].reduce((sum, x) => sum + x, 0));
Answer and explanation
Expected output: 6
Why: The accumulator starts at zero and receives every value.
Challenge 8. Default numeric sort
Predict the exact output before opening the answer.
console.log([10, 2, 1].sort());
Answer and explanation
Expected output: [1, 10, 2]
Why: Without a comparator, values are sorted as strings.
Challenge 9. Sparse array hole
Predict the exact output before opening the answer.
const a = [1, , 3];
console.log(a.length, 1 in a);
Answer and explanation
Expected output: 3, false
Why: The missing element is a hole, but array length remains three.
Challenge 10. filter(Boolean)
Predict the exact output before opening the answer.
console.log([0, 1, '', 2, null].filter(Boolean));
Answer and explanation
Expected output: [1, 2]
Why: Boolean removes every falsy value.
Challenge 11. Loose versus strict equality
Predict the exact output before opening the answer.
console.log(0 == false, 0 === false);
Answer and explanation
Expected output: true, false
Why: Loose equality coerces types; strict equality does not.
Challenge 12. Nullish coalescing
Predict the exact output before opening the answer.
console.log(0 || 10, 0 ?? 10);
Answer and explanation
Expected output: 10, 0
Why: || falls back for falsy values, while ?? only falls back for nullish values.
Challenge 13. Optional chaining
Predict the exact output before opening the answer.
const user = null;
console.log(user?.profile?.name ?? 'Guest');
Answer and explanation
Expected output: Guest
Why: Optional chaining returns undefined, then ?? supplies the fallback.
Challenge 14. Closure counter
Predict the exact output before opening the answer.
function make() {
let n = 0;
return () => ++n;
}
const next = make();
console.log(next(), next());
Answer and explanation
Expected output: 1, 2
Why: The returned function retains its lexical n binding.
Challenge 15. Arrow lexical this
Predict the exact output before opening the answer.
const user = {
name: 'A',
show() {
return (() => this.name)();
},
};
console.log(user.show());
Answer and explanation
Expected output: A
Why: The arrow captures this from the regular show method.
Challenge 16. Bound function receiver
Predict the exact output before opening the answer.
function show() {
return this.name;
}
const f = show.bind({ name: 'A' });
console.log(f());
Answer and explanation
Expected output: A
Why: bind creates a function with a fixed receiver.
Challenge 17. Promise before timer
Predict the exact output before opening the answer.
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');
Answer and explanation
Expected output: A, D, C, B
Why: Synchronous work runs first, then microtasks, then timer tasks.
Challenge 18. await continuation
Predict the exact output before opening the answer.
async function run() {
console.log(1);
await 0;
console.log(2);
}
run();
console.log(3);
Answer and explanation
Expected output: 1, 3, 2
Why: Code after await continues in a microtask.
Challenge 19. Promise error recovery
Predict the exact output before opening the answer.
Promise.reject('x')
.catch(() => 2)
.then(console.log);
Answer and explanation
Expected output: 2
Why: Returning from catch fulfills the next promise.
Challenge 20. Async map result
Predict the exact output before opening the answer.
const x = [1, 2].map(async (n) => n * 2);
console.log(x[0] instanceof Promise);
Answer and explanation
Expected output: true
Why: An async callback always returns a Promise.
Challenge 21. Destructuring defaults
Predict the exact output before opening the answer.
const [a = 1, b = 2] = [undefined, null];
console.log(a, b);
Answer and explanation
Expected output: 1, null
Why: Defaults apply to undefined, not null.
Challenge 22. Object key coercion
Predict the exact output before opening the answer.
const o = {},
a = {},
b = {};
o[a] = 'one';
o[b] = 'two';
console.log(o[a]);
Answer and explanation
Expected output: two
Why: Plain-object keys are coerced to the same string.
Challenge 23. Prototype lookup
Predict the exact output before opening the answer.
const parent = { role: 'admin' };
const user = Object.create(parent);
console.log(user.role);
Answer and explanation
Expected output: admin
Why: Property lookup follows the prototype chain.
Challenge 24. Delete reveals prototype
Predict the exact output before opening the answer.
const p = { x: 1 },
o = Object.create(p);
o.x = 2;
delete o.x;
console.log(o.x);
Answer and explanation
Expected output: 1
Why: Deleting the own property reveals the inherited one.
Challenge 25. Object.freeze is shallow
Predict the exact output before opening the answer.
const o = Object.freeze({ x: { n: 1 } });
o.x.n = 2;
console.log(o.x.n);
Answer and explanation
Expected output: 2
Why: The nested object is not frozen.
Challenge 26. React-style direct updates
Predict the exact output before opening the answer.
let count = 0;
const setCount = (v) => {
count = v;
};
setCount(count + 1);
setCount(count + 1);
console.log(count);
Answer and explanation
Expected output: 2
Why: This plain JavaScript model evaluates each update immediately; React batching differs, so discuss that distinction in an interview.
Challenge 27. Debounce timer replacement
Predict the exact output before opening the answer.
let id;
const debounce = (f) => (x) => {
clearTimeout(id);
id = setTimeout(() => f(x), 0);
};
const f = debounce(console.log);
f(1);
f(2);
Answer and explanation
Expected output: 2
Why: The second call clears the first pending timer.
Challenge 28. Promise.all result order
Predict the exact output before opening the answer.
Promise.all([Promise.resolve(2), 1]).then(console.log);
Answer and explanation
Expected output: [2, 1]
Why: Promise.all preserves input order after resolving values.
Challenge 29. Function hoisting
Predict the exact output before opening the answer.
console.log(add(1, 2));
function add(a, b) {
return a + b;
}
Answer and explanation
Expected output: 3
Why: Function declarations are initialized during scope creation.
Challenge 30. JSON clone limitation
Predict the exact output before opening the answer.
const a = { x: undefined };
const b = JSON.parse(JSON.stringify(a));
console.log('x' in b);
Answer and explanation
Expected output: false
Why: JSON serialization drops undefined object properties.
Continue practising
Revisit Parts 6 and 7 for larger output-based and coding practice sets, then return to the core handbook for architecture, system design, and behavioral preparation.