Search code examples
javascriptfunctionclosuresiife

Why does this function work? Shouldn't "executed" return to false every time the function is called?


This function is supposed to only ever run once. However I don't understand why every time it is called the variable executed doesn't return to false.

var onlyOnce = function() {
  var executed = false;
  return function() {
    if (executed == false) {
      executed = true;
      console.log("Code reached");
    }
  };
}();
onlyOnce();
onlyOnce();

This code prints only once. Why does this work?


Solution

  • It's because you're immediately executing a function and setting onlyOnce to that result. You could rewrite it like this:

    function createOnlyOnce() {
      var executed = false;
      return function() { // Return a new function
        if (!executed) { // I prefer this over == false
          executed = true;
          console.log('Code reached');
        }
      };
    }
    
    var onlyOnce = createOnlyOnce(); // Created a new function
    onlyOnce(); // Calls the generated function, not createOnlyOnce
    onlyOnce(); // Since we're calling the generated function, executed is still `true`
    

    What you end up with is a closure. This means that the value of executed can be used and changed inside of the generated function. Whatever you set it to, it will still have that value next time you call it (unless something else changes it, of course).