3

I often see that many event listener codes are wrapped inside IIFE (function(e){}()) I felt it is unnecessary to keep the event listeners inside IIFE. for example:

Without IIFE

jQuery(window).on("load", function(){
    console.log("inside plain load");
});

With IIFE

(function(){
    jQuery(window).on("load", function(){
        console.log("inside wrapped load");
    });
}())

If we include above code together in a js file, on load event they execute only based on the order it was written.

I know that IIFE invoke itself, but what is the use of having event listeners inside it?, anyways it's gonna fire only if the event happens.

  • Is there any need to wrap event listeners inside IIFE?
  • Is event listeners inside IIFE is really a good practice?
nonopolarity
  • 146,324
  • 131
  • 460
  • 740
Abel
  • 2,371
  • 3
  • 15
  • 29
  • 1
    There is no difference in those two sets of code you have listed. Reasons why you would do it is to declare variables, but keep them out of global scope. `(function(){ var foo; jQuery(window).on("load", function(){ foo = true; }) }())` – epascarello May 08 '20 at 13:50

3 Answers3

2

For your example there is no difference.

The main reason to use IIFE is to prevent leaking variables in the global scope.

(function(){
    let notLeakedVariable = 'something'
    jQuery(window).on("load", function(){
        console.log("inside wrapped load");
        console.log(notLeakedVariable)
    });
}())

Without IIFE you'll leak the variable in the global scope.

By wrapping your listener, you could even group multiple listeners and they'll share the same scope though closures.

(function(){
    let sharedVariable = 'something'
    jQuery(window).on("load", function(){
        console.log("inside wrapped load");
        // sharedVariable is accessible 
    });

    jQuery(selector).on("click", function(){
        // sharedVariable is accessible 
    });
}())
Radu Diță
  • 13,476
  • 2
  • 30
  • 34
2

You use IIFE because you want a local scope to isolate everything from the global scope.

(function() {
  var count = 0;
  
  document.body.addEventListener('click', function() {
    console.log("hi", count++);
  });
}());
hello world

In the above code, no one else in the world can touch count. Only the function that does the console.log can access it. So count is not contaminating the global scope, and is also protected from the outside world.

Note that the IIFE is providing a local scope. Some JavaScript expert may call it a closure, but closure has nothing to do with it here. All you want here is a local scope.

The function that does console.log, is a closure. It is a function that takes the scope chain and is able to access count. This is the behavior of a closure.

So this function has access to count, and nothing else does. So this IIFE provides a good way to write something self contained, not contaminate the outside world, and not let the outside world contaminate it.

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
1

It doesn't affect the way the callback is bound, but there are a few reasons why you might see it.

  1. If the JS file is loaded directly via tag, then the IIFE will close-over any variables created in the IIFE, and they won't be visible on the global window object. For example, if you wrote var x = 'foo' in the IIFE, it won't be visible as window.x, but it would be without the IIFE.
  2. Some functions return values that you don't want to expose. For example jQuery(window).on(...) actually returns something. You can't simply assign a variable in front of it and get it because of the IIFE.
alex
  • 756
  • 4
  • 12