0

I am using the modular pattern in JavaScript. I have three IIFEs in total:

  • The first one returns an object with a host of methods.
  • The second one does the same thing.
  • The third one calls the methods returned, therefore controlling the app’s logic.

All methods called inside the third IIFE are tied to an event listener for when you click anywhere in the document. If the third IIFE runs but doesn’t return, no closure is created, which means the third IIFE is popped off the stack and takes with it the variable object created during the creation phase of the execution context.

The event listener is saved in memory which calls all the returning methods from the first and second IIFE as they are global methods. However, also tied onto the event listener, is a private function that I want to run inside the third IIFE. If no closure is created in the third IIFE, how come when the click event on the document happens, the event listener recognises the private function in the third IIFE if the variable object pops off the stack with the third IIFE and is no more as no closure was created?

The controller IIFE has not returned so no closure is created and the event listener therefore calls a function that is not currently avaiable as the third IIFE has popped off the stack, does an event listener take with it a scope of when it was created? I understand how the returning methods are called as they are still global but I’m confused how the private function is called by an event listener after the third IIFE is finsihed.

See the code below. The first and second IIFEs are absent which return all the mehtods I have called in the event listener. Rather than bore you all with my long code in the project I am working on, I have simplified it below.

var scoreController = (function() {
  var score = 0;

  return {
    updateScore: function() {
      score++

      return score;
    }
  }
})();
var UIcontroller = (function() {
  return {
    updateUI: function(value) {
      document.querySelector("#displayScore").textContent = value;
    }
  }
})();
var controller = (function() {
  function setupEventListener() {
    document.addEventListener("click", updateGame);
  }

  setupEventListener();

  function privateFunction() {
    console.log("how does this work if")
  }

  function updateGame() {
    var globalScore = scoreController.updateScore();
    
    UIcontroller.updateUI(globalScore);
    privateFunction();
  }
})();
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Kevo
  • 15
  • 7
  • So, given `(function(){ function a(){}; addEventListener("click", a); })();`, you’re basically asking how the function `a` can still be accessed by `addEventListener`, even if the IIFE’s scope can no longer be accessed? Well, you passed `a` to `addEventListener`, so now, `addEventListener` has access to it. As long as it has access to `a`, it will never go “out of scope” or be garbage collected, etc. – Sebastian Simon Oct 03 '21 at 20:04
  • Related: [What is JavaScript garbage collection?](/q/864516/4642212), [What is the scope of variables in JavaScript?](/q/500431/4642212). – Sebastian Simon Oct 03 '21 at 20:08
  • Even if i dont assign the event listener to that function ? Using your example, I have assigned the event listener to a funciton which later goes onto call a(). The IIFE has finsished executing, i thought it would take function a with it as it has finished executing. Does funciton a remain in this case ? If so if function a uses variables inside the IIFE do they stay aswell ? thanks – Kevo Oct 03 '21 at 20:21

1 Answers1

0

The controller IIFE has not returned so no closure is created

This is a wrong conclusion. Every function can and does form a closure, if it is referenced from beyond the scope that the function is created in. It doesn't have to be returned from the IIFE for that - it could also be passed to another function, it could be stored in a global variable, or it could be attached as an event handler to the dom.

does an event listener take with it a scope of when it was created?

Yes. Every function does. updateGame closes over the variable privateFunction (and also over UIcontroller in a higher scope).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Yes i think that makes sense. So are you saying that becasue I referenced the privateFunction in a funciton that is passed to the eventListener then I have created a closure so that when the PrivateFunction is called during the updateGame function then it remains as it is referenced outside ( in an an event listener)? With that the function is accessible even after the IIFE has finshed and variables inside the IIFE stay as they would if i returned function to the global scope ? Thanks – Kevo Oct 03 '21 at 20:57
  • @Kevo Exactly that. – Bergi Oct 03 '21 at 21:02
  • 1
    Ive just joined stack Overflow. When i have 15 points ill be sure to upvote and accept your answer , thanks for your help! – Kevo Oct 03 '21 at 21:07