← Bytedance Interview Insights

Bytedance·Frontend Engineer·Technical Phone Screen·Intermediate

Intermediate
Jul 2026

Summary

Frontend phone screen at Bytedance that basically came down to one classic JavaScript closure question. Nothing crazy, but it's the kind of thing that trips you up if you haven't thought about it recently.

Questions Asked (1)

Q1

Given a for loop that uses setTimeout to log the loop counter, predict the output and explain why it behaves differently with var versus let. Walk through how you'd fix it.

Technical Trade-offsAlgorithms & Data Structures
Author's notes

The var vs let thing I knew, but I fumbled a bit explaining the event loop part.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by predicting the output for both var and let versions, then explain the underlying mechanisms (function scope vs block scope, closures, event loop). Finally, walk through multiple fixes, comparing their trade-offs and modern best practices.

Pro tip: Mention that while let is the modern fix, understanding the IIFE and bind solutions shows depth, and relate it to real-world scenarios like event handlers in loops to demonstrate practical experience.

1. Predict the output

State that with var, the loop logs the final value (e.g., 5) five times; with let, it logs 0,1,2,3,4 in order. Clarify that setTimeout is asynchronous and callbacks run after the loop completes.

2. Explain var behavior

Explain that var is function-scoped, so there is a single shared binding for i. All setTimeout callbacks close over the same variable, which has already been incremented to its final value by the time the callbacks execute.

3. Explain let behavior

Explain that let is block-scoped, so each iteration creates a new binding for i. Each callback closes over its own copy of i, preserving the value at the time of the setTimeout call.

4. Walk through fixes

Present multiple solutions: using let (modern), wrapping in an IIFE to create a new scope per iteration, using bind to pass the current value, or using forEach over an array. Compare their readability and compatibility.

5. Summarize trade-offs

Conclude that let is the cleanest and most recommended approach in ES6+, but understanding older patterns is useful for legacy code. Emphasize that the core issue is variable scoping and closure capture.

Key Points to Mention

  • Function scope vs block scope
  • Closures and how they capture variables
  • Asynchronous execution and the event loop
  • IIFE (Immediately Invoked Function Expression) as a traditional fix
  • Using bind to create a new function with a bound this and arguments
  • Modern ES6+ best practices and browser compatibility

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