0

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?

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • In javascript, the variables have scope in the containing brackets. In a sense, think of "executed" as global to the returned function, and hence retains its value when you change it. It is weird, but hey, this is javascript – Makketronix Jul 12 '16 at 22:25
  • Read about closures ... http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – Hector Barbossa Jul 12 '16 at 22:26

2 Answers2

2

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).

Mike Cluck
  • 31,869
  • 13
  • 80
  • 91
0

With the self-executing outer function, a closure is created. As a result, every execution of the returned function operates on the same instance of executed. This results in the observed behavior.

You should read up on closures, e.g. on MDN.

TimoStaudinger
  • 41,396
  • 16
  • 88
  • 94