Skip to content

Closure leaks

A closure is a function that captures variables from its enclosing scope. The entire captured binding stays alive while the function is reachable.

flowchart TD
  cb[callback array]
  fn1["() => huge.length"]
  huge[huge array 40k items]
  cb --> fn1
  fn1 --> huge

You only “use” huge.length — but the closure captures huge, not just .length.

const handlers = [];
function registerRow(row) {
const hugeContext = buildReportForAllRows(); // MB of data
handlers.push(() => formatCell(row, hugeContext));
}

Every handler retains the full hugeContext.

function registerRow(row, reportSlice) {
handlers.push(() => formatCell(row, reportSlice));
}
// Or compute per-row data outside the closure
function registerRow(row) {
const slice = extractSliceFor(row.id);
handlers.push(() => formatCell(row, slice));
}

Live demo: closure over large scope

Small callbacks retain an entire large array via closure.

— MBPeak: — MB