Write a function once(fn) that lets fn run only the first time it is called.
Return a wrapper that keeps a called flag and the first result in a closure. On the first call, run fn and store the result; on later calls, return the stored result without running fn.
Explain it simply
Think of a one-time password slip: the first scratch reveals the code, and after that the slip is dead. once wraps any function so the real work happens a single time.
The wrapper needs memory between calls, and a closure provides that. Two variables live in the closure: whether we have run yet, and what the first run returned.
Line by line
function once(fn) {
let called = false;
let result;
return function (...args) {
if (!called) {
called = true;
result = fn.apply(this, args);
}
return result;
};
}
const init = once((name) => {
console.log("setup for " + name);
return 42;
});
console.log(init("app")); // Output: setup for app
// Output: 42
console.log(init("again")); // Output: 42What to say in the interview
"I keep a called flag and the first return value in a closure. The first call runs fn with the original this and arguments and caches the result; later calls just return it. It is useful for one-time initialisation like opening a connection."
Complexity
Time O(1) per call besides fn itself. Space O(1) for the flag and one cached result.
Common mistakes
- Forgetting to return the cached result on later calls.
- Dropping this and arguments by calling fn() instead of fn.apply(this, args).