4

I'm trying to understand the difference between:

(function(document) {
    //do stuff with document
})(document);

and

(function() {
    //do stuff with document
})();

I'm unsure why the convention appears to be to pass document and sometimes window too to the function? Is it to do with scope?

tommyd456
  • 10,443
  • 26
  • 89
  • 163

3 Answers3

6

This becomes especially handy if you use a compressor/uglifier like UglifyJS. It then replaces document with say a, making your code shorter.

So something like

(function(document, window){
  var body = document.body;
  var foo = document.querySelector('foo');
  var bar = document.querySelector('bar');
})(document, window);

becomes

(function(a, b){
  var c = a.body;
  var d = a.querySelector('foo');
  var e = a.querySelector('bar');
})(document, window);

If you did not place document and window in the function it'll just keep saying document;

(function(){
  var c = document.body;
  var d = document.querySelector('foo');
  var e = document.querySelector('bar');
})();
Erik Terwan
  • 2,710
  • 19
  • 28
2

An immediately invoking function expression (IIFE) creates a new local scope. Just like any function, you can pass in arguments when you call it. document and window are globals in JavaScript web api, and are made available when you run js in the browser. By passing them into an IIFE, you can access them as whatever you want inside due to scope. For example:

(function(w, d) {
  console.log(w); // window
  console.log(d); // document
})(window, document);

console.log(w); // Uncaught ReferenceError: w is not defined
console.log(a); // Uncaught ReferenceError: a is not defined

The reason w and a are not defined in the second set of console.logs is because they are locally scoped to the IIFE.

Nick Salloum
  • 2,158
  • 12
  • 13
1

There are some reasons for this:

1. Using less global variables By injecting the function with the global variable it will depend on only the argument and not a global variable which might be used multiple times.

2. Creating a local scope An IIFE is a way to create a new scope by declaring a function and immediately invoking it. See this question for more information.

3. Better minify

For example if you will minify your example it will change from this:

(function(document) {
    //do stuff with document
})(document);

To this:

(function(a) {
    //do stuff with a
})(document);

Notice the a, which is shorter than your document.

Edit: Fixed typos

Community
  • 1
  • 1
Eran Shabi
  • 14,201
  • 7
  • 30
  • 51
  • Useful link. Found this which answers this for me: "Performance benefit of using IIFE’s is the ability to pass commonly used global objects like window, document etc as an argument by reduce the scope lookup.(Remember Javascript looks for property in local scope and way up chaining till global scope). So accessing global objects at local scope reduce the lookup time like below." – tommyd456 Nov 25 '16 at 16:42