7

In some Javascript code which uses immediate function, it has argument window or document like the following:

(function (window, document) {
  ...
})(window, document);

However, window and document are global objects and can be directly accessed as follow:

(function () {
  var userAgent = window.navigator.userAgent;
  ...
  var el = document.getElementById(...)
  ...
})();

What are the differences between the above two codes. Which is better way and why?

ntalbs
  • 28,700
  • 8
  • 66
  • 83
  • 1
    Doing so allows you to modify the actual values of `window` and `document` within that scope; e.g. things are different for Node. – Ja͢ck Aug 27 '13 at 02:56

3 Answers3

4

Two reasons I can think of:

1) Local variables are the first in the scope chain, so their access is faster than globals (with faster I mean insignificantly faster).

2) Inside the function, window and document are local variables, so their names can be minimified:

(function (w, d) {
//var userAgent = w.navigator.userAgent;

)(window, document);
Marlon Bernardes
  • 13,265
  • 7
  • 37
  • 44
4

What are the differences between the above two codes. Which is better way and why?

In all practicality and usage in browsers only, there's no appreciable difference.

That said, there's a very slight performance increase that comes from referencing local variables instead of globals.

Also, it allows the flexibility of swapping out the real window by a mock version; this could be useful during testing and in certain environments where some of the objects are not available and must be replaced.

Btw, there's another kind of argument you could pass, which is undefined; it goes like this:

(function(undefined) {
    // your code
}());

You don't actually pass anything to the outer function and by doing so you make sure that undefined has not been tampered with; pedantic people like myself would just void 0 for that purpose though :)

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
-1

The difference is polymorphism: in the first case, you could pass the function any pair of objects that behave as the window and the document objects (at least for the methods your function calls), and the function will work too with them.

In practice, with this two objects in particular, it's more error prone that any benefit - everyone expects window and document to be the window and document defined by Javascript. But in theory, that's the gain.

mgarciaisaia
  • 14,521
  • 8
  • 57
  • 81
  • *“it's more error prone”* I don't understand why that should be. It seems more robust to me: if you run the script in an environment that doesn't have `window`, you can swap it out by modifying only one line. Duck typing is a feature of dynamically-typed languages, not a weakness. – Waleed Khan Aug 27 '13 at 03:07
  • Provided one expects `window` and `document` to be _those_ `window` and `document` we all know, having a relatively large function with those variables redefined can lead to mistakes by quick patching a function or the like. They're not constants, but one expects them to behave like that. I would call them with a different name - that's my point. – mgarciaisaia Aug 27 '13 at 13:07