10 Popular Front-End Interview Answers Ran Against Real Code: 6 Are Flat Wrong
Interview question banks are everywhere, each with a "standard answer" attached.
The problem is: who wrote these answers? When? Has anyone actually run them?
I picked the 10 most widely circulated front-end questions, located the original answer text in real question banks (sources recorded in the experiment archive), then ran each one with Node 24 and a real browser, using official documentation as judge. The scoring rules were fixed before running: A = reciting it gets you wrong; B = you can bluff but fall apart under follow-up; C = completely correct.
Here are the results first:
| # | Question | Circulated answer | Score | Measured truth |
|---|---|---|---|---|
| 1 | How much can localStorage store? | 5MB | A wrong | Measured 5,222,400 characters; ASCII content ≈ 10MB |
| 2 | How many JS data types? | 6 | B outdated | Now 7 primitives + object = 8; bigint from ES2020 is missing |
| 3 | Is Object.assign a deep copy? | Deep copy for one-level properties | A wrong | Always a shallow copy; mutating nested properties changes both |
| 4 | JSON method for deep copy | Simplest deep copy solution | B incomplete | Date becomes string, undefined is lost, circular references throw |
| 5 | Does let hoist? | No hoisting | A wrong | The error message itself proves it hoists; it just can't be touched |
| 6 | Is const value immutable? | Value cannot change | B one-sided | It locks the binding, not the value; obj.a = 2 doesn't throw |
| 7 | setTimeout(fn, 0) | Runs as soon as possible (no one explains further) | B incomplete | Nested past level 7 gets throttled to 4ms; measured [0,0,0,0,0,0,5,5] |
| 8 | GET length limit | 2048 characters / 2KB | A wrong | Chrome sent a 1MB URL and got 200; 2048 is an IE relic |
| 9 | Promise.all with one failure | Terminates subsequent processing | A wrong | The other 4 requests still finish; only the result is discarded |
| 10 | Cookie limit per domain | 20 | A wrong | Chrome measured ~180; RFC minimum is 50; off by 9x |
10 questions, 6 A, 4 B, 0 C.
Not a single circulated answer fully holds up. Below, sorted by damage, each one explained.
localStorage: 5MB memorized for a decade, and the unit is wrong
Question bank original (same text from Blog Park, CSDN, Tencent Cloud, Juejin, Nowcoder): "Storage capacity is 5MB."
I wrote a loop in Chrome to stuff data into localStorage until it threw QuotaExceededError:
storedChars: 5222400 // 51 blocks of 100KB, then it blew up
err: "QuotaExceededError: ... exceeded the quota."
5,222,400 characters. MDN original: "The keys and the values stored with localStorage are in the UTF-16 string format" — the quota counts characters, not bytes.
5M characters of ASCII content is 10MB on disk. The spec's recommended value is 5 MiB per origin, counted in UTF-16 code units — "5M characters" mutated into "5MB" in transmission.
Verdict: wrong. Off by double, unit-level error. If an interviewer follows up with "what about 4M Chinese characters?", someone who memorized 5MB freezes — a Chinese character is also one code unit, so it's still 5M characters, but many people think Chinese characters count as 2 bytes and need to be halved.
Cookie 20 limit: this answer is from 2010
Nowcoder's "Classic Front-End Interview Questions Collection" opens with: "At most 20 cookies can be generated per domain." Juejin's 30K combo, Zhihu's 32,000-word summary, Tencent Cloud's 42 HTML5 questions — identical sentence, no variation, copied for a decade.
The original actually contains a clue: "IE6 or lower can only have up to 20 cookies." 20 is IE6's number.
The real value today: RFC 6265 requires browsers to support at least 50 cookies per domain; Chromium source has a hard-coded constant kDomainMaxCookies = 180. I wrote 300 cookies to the same domain and Chrome kept 176 — beyond that it silently evicts the oldest, without even a warning.
attempted: 300
kept: 176 // q0~q92 already silently evicted
Verdict: wrong. Someone who memorized 20 writes a 21st cookie on a real machine and gets nothing; that's where the resume goes.
let doesn't hoist? The error message disagrees first
Question banks in unison: "var has variable hoisting; let and const do not have variable hoisting" (Tencent Cloud autumn recruitment combo, Juejin, Blog Park, three identical).
Run it:
try {
void x; // let x declared later
} catch (e) {
console.log(e.message);
}
// Cannot access 'x' before initialization
Look at the error text: "Cannot access 'x' before initialization". Not "x is not defined".
The engine recognizes the variable — the binding is already established, but it can't be touched before initialization. This region is called the temporal dead zone (TDZ). The error itself is evidence of hoisting. If let truly didn't hoist, the error would be identical to accessing a never-declared variable.
The control group var: accessing before declaration returns undefined, no error — that's what "hoisted and directly accessible" actually looks like.
Verdict: wrong. Someone who recites "doesn't hoist" gets asked in round two "then why isn't the error message is not defined?" and it's over.
Promise.all doesn't "terminate" any request
For this one I found a freshly wrong source — a CSDN article from this April, original words: "As long as any one fails, it immediately returns the failure result and terminates subsequent processing."
Running it exposes the lie:
let started = 0, finished = 0;
const job = (ms) => new Promise((res, rej) => {
started++; // request sent, counted synchronously
ms === 0 ? rej(new Error('boom'))
: setTimeout(() => { finished++; res(1); }, ms);
});
Promise.all([job(0), job(40), job(40), job(40), job(40)]).catch(() => {});
setTimeout(() => console.log(started, finished), 120);
// 5 4 ← after reject, the other 4 still completed
All 5 tasks were sent; after one fails at 40ms, the remaining 4 all complete. No matter how fast Promise.all rejects, it cannot retrieve requests already sent — it only discards the results, it doesn't cancel. To actually cancel, you need AbortController.
Verdict: wrong. The phrase "terminates subsequent processing" conflates "Promise.all rejects" with "requests are cancelled." Interviewers love to bait this exact hook.
GET 2048 characters: the protocol has no such rule; IE did
"URL maximum length is 2048 characters" — Tencent Cloud testing bank, Zhihu daily question, CSDN interview questions, three identical, many adding "HTTP protocol stipulates."
RFC 9112 original: "HTTP does not place a predefined limit on the length of a request-line". The protocol has never set any length limit.
Real test: a local server with no length limit received GETs from Chrome:
16KB → 200 512KB → 200
64KB → 200 1MB → 200
2MB → Chrome refuses to send (client-side limit)
A 1MB GET goes through no problem. Meanwhile on the same machine, Python's built-in test server returns 414 at 64KB, Nginx's default rejects at 8KB — each implementation has its own taste, and every number is different; 2048 belongs to none of today's mainstream. It's an IE-era relic.
Verdict: wrong. Saying "the protocol limits to 2KB" is itself a deduction. The correct posture: the protocol has no limit; browsers and servers each have limits; Chrome's client-side cap is about 2MB; check the docs of your target service for the specific number.
Object.assign: "deep copy for one-level properties" — it is always a shallow copy
Blog Park and CSDN question banks carry the same text: "When an object has only one level of properties and no second-level properties, this method is a deep copy; but when the object contains an object... it's a shallow copy."
It sounds plausible, but it's describing "looks like" as "is." When an object has no nested properties, shallow and deep copy have no observable difference — because there are no references to share. That's not "it becomes a deep copy," that's "there's nothing to test."
MDN states plainly: "Object.assign() only copies property values... if the source value is a reference to an object, it only copies that reference value." By classification, it is always a shallow copy.
Verdict: wrong. The bank author tried to help with an intuition about "copy depth" and ended up inventing a false category. Answering this way tells an interviewer you haven't read the documentation.
JSON deep copy: passes first-round interviews, breaks in production
"Deep copy with JSON.parse(JSON.stringify()) is fine" — question banks present it as the simplest solution, and most omit the cost.
I counted what it actually drops:
const cp = JSON.parse(JSON.stringify({
d: new Date(), // "1970-01-01T00:00:00.000Z" Date becomes string
u: undefined, // field disappears entirely
nan: NaN, // null
inf: Infinity, // null
re: /x/g, // {}
m: new Map(), // {}
s: new Set(), // {}
}));
// circular reference → TypeError: Converting circular structure to JSON
Seven sins, all reproduced on a real machine. Production code should use structuredClone() — available in browsers and Node 18+ — and avoids all these traps. (I wrote a separate seven-trap test for JSON.stringify itself last month; here we count only the deep-copy battle.)
Verdict: B. Calling it "the simplest solution" is true; the bank's error is omitting the cost entirely. Someone who memorized it writes tracking code that drops undefined fields and spends a day debugging it.
"6 data types" — your question bank stopped in 2019
"JS has a total of six basic data types... plus Symbol added in ES6" — CSDN, segmentfault, Zhihu, nearly identical word-for-word.
That answer was correct in the Symbol era. But ES2020 added bigint; run it:
typeof 10n // 'bigint'
The correct answer now: 7 primitive types (number, string, boolean, undefined, null, symbol, bigint) + object = 8 types.
Verdict: outdated. Data types are the opening question; answering "6" makes an interviewer silently label you "hasn't updated knowledge" — every question after goes against you.
const: it locks the binding, not the value
Interview bank original: "const declares a read-only constant. Once declared, the constant's value cannot change." — no mention of objects.
Run it:
const obj = { a: 1 };
obj.a = 2; // no error, obj.a === 2
obj.a = 3; // still no error
const z = 1;
z = 2; // TypeError: Assignment to constant variable
const locks the binding between name and value, not the value itself. Primitive values are immutable so they look like "constants," but object properties can be freely changed. For actual freezing, Object.freeze().
Verdict: one-sided. Someone who memorized the line hesitates on const arr = []; arr.push(1); hesitation is a flaw.
setTimeout(fn, 0): the bank only got half of it
This one is the exception — banks commonly teach "not immediate execution," which is right. But they all stop there; no one asks the next question: the fastest it can be?
I measured the delay curve for nested timers:
Nesting levels 1-6: actual delay 0ms
Nesting levels 7, 8: actual delay 5ms
The HTML spec writes it hard: beyond 5 nested levels, the minimum interval is forced to 4ms. That's why [0,0,0,0,0,0,5,5] — the first 6 levels are free to be fast, the 7th onward the browser slams the brakes (to prevent nested timers from starving the page).
Verdict: incomplete. "0ms is the fastest scheduling" gets you through round one; the follow-up "what about nesting? what's the minimum delay?" gets silence. The gap in interview performance has always been that second half-sentence.
Why do standard answers fail collectively?
Reviewing these 10 questions, the error sources boil down to three:
Fossil layer. localStorage 5MB, cookie 20, GET 2048 — all IE-era facts copied into question banks, copied for a decade without verification. The original text clearly says "IE6", but copiers only copy the conclusion, not the condition.
Never ran the code. For let hoisting, Promise.all, Object.assign — the authors would have seen their mistake if they'd run the code once. Question banks are products of copying, not experimentation.
Transmission drops qualifiers. "5 MiB per origin (counted by code unit)" became "5MB"; "IE6 max 20" became "20 per domain"; "the protocol has no limit, implementations do" became "the protocol limits to 2KB". Each retelling strips a layer of qualification.
Why do interviewers love follow-up questions? Because round one listens for the answer; round two listens for boundaries. People who memorize banks ace round one and fail round two — this 10-question 0-for-all is the proof.
Experiment boundaries, stated upfront
Single machine, single browser (Node 24.14.1 + local Chrome). Numbers may float with versions; the method is more reliable than the values. The question bank sample was 10 questions, not a full census. "Circulated answers" refer to real, searchable question bank pages; each has a source on file. The experiment archive and Node scripts are reproducible.
Your turn
These 10 are the highest-coverage questions, the ones with the most uniform errors. Errors in obscure banks are only more numerous.
Comment with one: which "standard answer" did you memorize, then find out was wrong? I'll collect a batch and write a sequel in the next post — picking questions where commenters stepped in pits, and continuing real-machine verification.