0

I'm doing some experimenting with closures in Javascript, and with AngularJS directives (1.x) in particular.

To put it simply, I am wondering why ScenarioOne correctly captures the variable message that we want, while ScenarioTwo does not. Why does the IIFE not capture and maintain the desired value of message when it invokes itself?

SCENARIO ONE

 // WORKS. Displays 'We want this message'

  var message = 'We want this message';

  element.bind('click', (function(){
    var msg = message;   // <-- MAGIC ?
    return function(){
      element.append('<p>Value of message: ' + msg + '</p>');
    };
  })());

  message = 'We DON\'T want this message';

SCENARIO TWO

 // DOES NOT WORK. Displays 'We  DON'T want this message'
  var message = 'We want this message';

  element.bind('click', (function(){
    return function(){
      element.append('<p>Value of message: ' + message + '</p>');
    };
  })());

  message = 'We DON\'T want this message';

I would like to understand, what are the magic mechanics (see line denoted <-- MAGIC ) of that assignment? What is the general rule about this? Do all variables that you want from an outer scope need to explicitly assigned to a new variable inside the IIFE?

Here is a working Plunkr of all this: https://plnkr.co/edit/1M9yrzuOi0bzNHxbb5rO

CodyBugstein
  • 21,984
  • 61
  • 207
  • 363
  • `msg` isn't changed before the function is called. That's why it works. I'm not sure of what's unclear to you. Did you read https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript?rq=1 ? – Denys Séguret Sep 17 '18 at 15:09
  • 1
    See the linked question's answers. There's no magic involved. :-) In your second example, by the time your callback runs, you've changed the value of the `message` variable, so naturally you see the updated value when it's used in the `append` call. A closure closes over **the variable** ¹, not the variable's *contents* as of when the closure was created. *(¹ More accurately, it closes over the lexical environment object that contains the variable, but that's a detail...)* – T.J. Crowder Sep 17 '18 at 15:14
  • Ok thanks I will read through the answers at the linked question. I guess I understood it wrong. I thought the IIFE creates it's own new version of the variables, beginning with their last value from the outer scope – CodyBugstein Sep 17 '18 at 15:17
  • The IIFE only provides a scope, and creates the variable `msg` in that. It doesn't really close over anything. The function that you return from the IIFE and bind to the event is the actual closure - and in one case it closes over `msg`, in the other case if closes over `message`. – Bergi Sep 17 '18 at 16:02

0 Answers0