← Bytedance Interview Insights

Bytedance·Frontend Engineer·Technical Phone Screen·Intermediate

Intermediate
Apr 2026

Summary

Bytedance frontend screen, pretty JS-heavy. They threw a classic var/let loop question at me and wanted a full breakdown of what prints and why, not just the answer.

Questions Asked (1)

Q1

Given a for loop using `var` with a `setTimeout` inside, what does the code print and in what order? Then explain what changes if you swap `var` for `let`, covering scope differences, closure behavior, and sync vs async execution order.

Technical Trade-offs
Author's notes

I knew the punchline (all 5s with var, 0 through 4 with let) but fumbled explaining why the console.log after the loop fires before any of the timeouts.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by tracing the exact output of the var version, emphasizing that all setTimeout callbacks run after the loop completes and share the same variable. Then contrast with let, explaining how per-iteration bindings create a new closure for each callback, and clarify the synchronous loop execution versus asynchronous callback scheduling.

Pro tip: Mention that the output order is determined by the event loop: the loop runs to completion synchronously, then timers fire in order of their delay (all 0ms here, so in registration order). This shows you understand both closure and async timing.

1. Analyze var behavior

Explain that var is function-scoped, so the loop variable is shared across all iterations. The setTimeout callbacks capture the same variable, which after the loop has the value 5 (if loop runs 0-4). Thus, all callbacks print 5.

2. Explain execution order

Clarify that the for loop runs synchronously to completion, scheduling five setTimeout callbacks. The callbacks execute asynchronously after the current call stack clears, in the order they were scheduled (since all have 0ms delay). So the output is five 5's, each on a new line, after the loop finishes.

3. Contrast with let

Describe that let is block-scoped, so each iteration of the loop creates a new binding for the loop variable. Each setTimeout callback captures its own unique variable, preserving the value at the time of scheduling. Thus, the output is 0, 1, 2, 3, 4 in order.

4. Discuss closure and scope differences

Highlight that with var, all closures share the same variable environment, while with let, each closure gets its own lexical environment per iteration. This is a key difference in how JavaScript handles block scoping and closures.

5. Summarize sync vs async

Reiterate that regardless of var or let, the loop itself is synchronous and the setTimeout callbacks are asynchronous. The order of output is always: loop completes first, then callbacks fire in order. The difference is only in the values printed.

Key Points to Mention

  • var is function-scoped, let is block-scoped
  • Closures capture variables by reference, not value
  • The event loop schedules setTimeout callbacks after the synchronous loop finishes
  • With var, all callbacks share the same variable, so they print the final value (e.g., 5)
  • With let, each iteration creates a new binding, so each callback prints its iteration value (0,1,2,3,4)
  • The output order is always sequential (0,1,2,3,4 or 5,5,5,5,5) because timers with same delay fire in registration order

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.