Problem
You want to create a generic function that converts a function to a function that can only be called once.
Ingredients
- a closure
 - the 
applymethod 
Directions
- 
Given: a function that executes only once (based on yesterday’s recipe).
function printSomething() { let called = false; if(called) { return undefined; } else { called = true; console.log('something'); printSomething = function() {}; } } printSomething(); // (1) Ok printSomething(); // (2) Does nothing - 
Create a function
once()that accepts a function as parameter and returns another function.function once(fn) { return function() { ... } } - 
Add a variable to memorize if the function has been called.
function once(fn) { let called = false; return function() { ... } } - 
Inside the returned function check that variable. If it is
true, then returnundefined…function once(fn) { let called = false; return function() { if(called) { return undefined; } ... } } - 
… otherwise set the variable to
trueand call the passed function.function once(fn) { let called = false; return function() { if(called) { return undefined; } else { called = true; fn.apply(this, arguments); } } } - 
Optimization: use
void 0instead ofreturn undefined, which are less characters.function once(fn) { let called = false; return function() { if(called) { void 0; } else { called = true; fn.apply(this, arguments); } } } - 
Optimization: replace
ifandelsewith the ternary operator.function once(fn) { let called = false; return function() { return called ? void 0 : ((called = true), fn.apply(this, arguments)); } } - 
Optimization: use a fat arrow function for
once().const once = (fn) => { let called = false; return function() { return called ? void 0 : ((called = true), fn.apply(this, arguments)); } } - 
Now remove all the boilerplate logic from
printSomething()and useonce()to create another functionprintSomethingOnce().function printSomething() { console.log('something'); } let printSomethingOnce = once(printSomething); - Voilá, now if 
printSomethingOnce()is called a second time, it simply does nothing. 
```javascript
function printSomething() {
  console.log('something');
}
let printSomethingOnce = once(printSomething);
printSomethingOnce();        // (1) Ok
printSomethingOnce();        // (2) Does nothing
```Alternative recipes
- Use a self-defining function.