2. Array sortEasy
For scores [9, 10, 100, 25], the leaderboard shows 9, 25 and 100 as the top three.
- function topScores(scores) {
- return scores.sort().reverse().slice(0, 3);
- }
Which line has the bug?
Show answer
Answer: Line 2: return scores.sort().reverse().slice(0, 3);
Without a comparator, sort compares elements as strings, so "10" < "100" < "25" < "9". Use scores.sort((a, b) => b - a). Note that sort also mutates the caller's array; toSorted doesn't.
4. Environment variablesEasy
The new checkout is on in production even though the deploy sets NEW_CHECKOUT=false.
- function checkoutVersion() {
- if (process.env.NEW_CHECKOUT) {
- return 'v2';
- }
- return 'v1';
- }
Which line has the bug?
Show answer
Answer: Line 2: if (process.env.NEW_CHECKOUT) {
Environment variables are always strings, and "false" is a non-empty string, so it’s truthy. Compare explicitly: process.env.NEW_CHECKOUT === "true", ideally in one config module that parses every setting.
7. Closures and scopeEasy
This logs 3, 3, 3. Change one word so it logs 0, 1, 2.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i));
}
var → letsetTimeout → setIntervali++ → ++iconsole.log → console.info
Show answer
Answer: A. var → let
let creates a fresh i for each loop iteration, so each callback closes over its own value. var shares one variable that's 3 by the time the callbacks run.
8. Parsing numbersEasy
An import reads amounts like "1,234.50". What do parseFloat and Number make of it?
console.log(parseFloat('1,234.50'), Number('1,234.50'));
What does it output?
- 1 NaN
- 1234.5 1234.5
- NaN NaN
- 1234.5 NaN
Show answer
Answer: A. 1 NaN
parseFloat reads as far as it can and stops at the comma, giving 1, a silent and wrong answer. Number rejects the whole string with NaN, which at least fails loudly. Strip the grouping separators for the source locale before parsing.
9. Currency formattingEasy
Prices should show as "$1,234.50" for US users and "1.234,50 €" for German users. What’s the right tool?
Intl.NumberFormat with the locale and style: "currency"toFixed(2), then replace the dots with commas for Germany- A regex that inserts a thousands separator every three digits
toLocaleString() with no arguments, which picks the right currency for you
Show answer
Answer: A. Intl.NumberFormat with the locale and style: "currency"
new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" }).format(1234.5) gives "1.234,50 €". Create the formatter once and reuse it; the currency must come from your data, not the locale.
13. TypesEasy
The validator rejects every list of tags. What fixes it?
if (typeof tags !== 'array') throw new Error('tags must be a list');
typeof tags !== 'array' → !Array.isArray(tags)!== → !='array' → 'Array'typeof tags → tags.constructor
Show answer
Answer: A. typeof tags !== 'array' → !Array.isArray(tags)
Arrays are objects, so typeof says 'object'. Array.isArray is the reliable check, even across iframes.
14. Removing array itemsEasy
Removing an item leaves an "empty" gap, and the list still reports the same length. What fixes it?
delete items[i];
delete items[i] → items.splice(i, 1)delete items[i] → items[i] = nulldelete items[i] → items.slice(i, 1)delete items[i] → delete items[i - 1]
Show answer
Answer: A. delete items[i] → items.splice(i, 1)
delete removes a property, leaving a hole in the array. splice(i, 1) removes the element and shifts the rest; items.filter((_, j) => j !== i) does it without mutating.
15. Number formattingEasy
withTax(10) returns "101.30" instead of 11.3. What fixes it?
function withTax(price) {
const tax = (price * 0.13).toFixed(2);
return price + tax;
}
(price * 0.13).toFixed(2) → Math.round(price * 13) / 100(price * 0.13).toFixed(2) → (price * 0.13).toFixed(0)return price + tax → return ${price + tax}``return price + tax → return price.concat(tax)
Show answer
Answer: A. (price * 0.13).toFixed(2) → Math.round(price * 13) / 100
toFixed returns a *string*, and 10 + "1.30" concatenates. Keep money as numbers (ideally integer cents) and format with toFixed or Intl.NumberFormat only when displaying.