Lots of people are doing this nowadays:

(function(window, $, undefined){
  // my special module
}(window, jQuery));

If you’re using this, it’s probably not needed. It’s usually just redundant cruft. The IIFE itself is okay (i.e. (function(){...}())). It’s the arguments that are the problem.

This strange concoction is used to protect a module’s scope from the environment in which its placed.

I have some bones to pick though…

If you can’t trust the window variable, then what can you trust? And you’re not even guaranteeing anything by passing it in. Some script could still overwrite it before you arrive. And the window object is still available for other scripts to mutate as they please, even after your have passed it in.

And you can’t trust jQuery either? You think some prototype.js imp is going to somehow travel into your code and re-assign the global dollar symbol? Ok ok, this may be permissible if you’re creating a third-party jQuery script, but certainly not if you have full control of your app.

Most importantly, who the hell overwrites undefined? Again, if you’re having to protect against this then you should deal with that issue directly. Go and knock on Bob’s door and tell him to stop overwriting undefined!

I know, I know. You’re writing a third-party script which may be placed in hostile environments. But here’s the thing: for every potential breach that you’re “protecting” yourself from there are a near-infinite amount of other things that someone could do to mess up your script, and you can’t protect yourself against all of them!

In my opinion, it’s acceptable for your code to be sensitive to the assumptions it makes about its environment. Yes, Bob, my module/plugin/library is going to mess up if you decide to overwrite undefined, and you should expect it to. Why should we protect ourselves from this imaginary (and probably non-existent) behaviour? I would love to know who overwrites undefined. Do you? If you do, then stop it.

I’m definitely not having a go at the general pattern of (i.e. the humble IIFE):

(function(){   }())

Actually, it’s incredibly useful in places. It allows me to create and run in a fresh scope which means I don’t have to risk polluting the global namespace.

Passing undefined though… The only possible benefits it gives are: a potential minuscule performance improvement due to a slightly lesser scope lookup (so miniscule that you’d be crazy to care). Also, it provides you with the possibility to use an alias like undef, but I’m not sure how helpful that really is anyway. And what’s wrong with var undef;?

Also, for readability’s sake, don’t pass so many things into your module’s main IIFE. It means the reader has to scroll all the way to the bottom just to see what each value is.

So, to sum up, this pattern:

(function(window, $, undefined){
  // all ma code
}(window, jQuery));

… is not the cure people claim it to be.

Thanks for reading! Please share your thoughts with me on Twitter. Have a great day!