10. Implement once(fn) — Run a Function a Single Time

easy

A small closures question, often a lead-in to harder ones. The cleanliness of your answer is the signal.

The idea

A boolean flag plus a stored result. Run fn on the first call, cache what it returns, and short-circuit forever after.

Two niceties that impress:

  • fn.apply(this, args) so the wrapped function keeps its receiver and arguments.
  • fn = null after the first run releases the closure's hold on fn for garbage collection.

Follow-ups

  • "Reset support?" → expose result.reset = () => { called = false; }.
  • "Relation to lodash.once / memoize?" → once is memoize that ignores arguments entirely.

What to practice

Write it, then add a reset() method without leaking state between resets.

More questions

index.js
function once(fn) {
  // your code here
}

const init = once(() => { console.log('init'); return 42; });
init(); // logs "init", returns 42
init(); // returns 42, no log

Tests

Test Code

Enter JavaScript that runs after your solution. It should return a value or a Promise.