1
\$\begingroup\$

Is there any point in wrapping this code in the self executing function declaring window and undefined? I've read that it improves performance etc... (NOTE I will be making use of the window at some point).

(function (window, undefined) { // THIS BIT HERE!
  var App = {
    init: (function () {
      $(document).ready(function () {
        App.alertMessage('Hello world');
      });
    })(),
    alertMessage: function (message) {
      alert(message);
    }
  }
})(window); // end closure
\$\endgroup\$
1
  • \$\begingroup\$ If all you ask is why are those two arguments declared, then I think @dystroy's answer puts it simply. If you're also asking why the self-executing function in the first place: it prevents you from polluting the global object with variables you declare with vars. \$\endgroup\$
    – Attila O.
    Feb 21, 2013 at 19:25

2 Answers 2

1
\$\begingroup\$

The IIFE/SEFE/closure/whatever

A quick discussion why we use "closures" for creating our code is that the purpose of the closure/IIFE/SEFE/whatever you want to call it, is to provide a scope where you are free to declare any variables for the internals to use, without polluting the global scope:

(function(ns){

  //I can declare tons of variables and functions here
  var a,b,c,d,e,f,g ...;

  //expose only foo to the namespace
  ns.foo = function(){
    //and foo can use them here
  }

}(this.myNS = this.myNS || {}));

//but out here, we call foo, use those variables
//but none of those variables are visible
myNS.foo();

//no a,b,c,d,e,f,g ... out here

window

Now, in the case of window, the idea that they are passed into the function is to have a local reference of whatever was pointed by them. It's because of the usage of that IIFE/SEFE/closure and how the compiler works.

//-3-found "a" here
var a = 1
(function(ns){
  //-2-no "a" here, going up
  ns.foo = function(){
    //-1-no "a" here, going up
    console.log(a);
  }
}(this.myNS = this.myNS || {}));

myNS.foo();

A quick trip into the how the compiler works is that when it tries to look for a variable/function, it searches through the local function scope first. If that variable/function is not found, it will look for it in the outer/containing scope. This goes on until the compiler finds that value or when you reach the global scope and declares it as non-existent.

In the code above, you crossed 2 scopes in order to find a. If a was declared lower into the scope, you could have minimized crossings. Now, wouldn't it be better if you provided window locally instead of having the compiler find it? YES, although:

  • performance gain is almost negligible
  • code structure might be more important than this minor optimization

undefined

For undefined, it's because undefined is mutable (it's not constant/final). Its value can be changed so that it would not be undefined anymore (but somewhat "pseudo-defined"). A quick code about that can be found here:

var a = {};
a.b === undefined; // true because property b is not set
undefined = 42;
a.b === undefined; // false, because undefined is something else

So what they did to overcome this "definable undefined" was to pass nothing into the function, and by default, passing nothing to the function and naming it something in the function gives it the value of "true undefined".


Personally, I don't pass in window and undefined into my closure for some reasons:

  • I don't check potentially undefined values against undefined. Since undefined values are falsy, loose comparison will tell if it is undefined or more like "unusable":

    //instead of this:
    if(potentiallyUndefined === undefined){...do stuff...}
    if(typeof potentiallyUndefined === 'undefined'){...do stuff...}
    
    //you can do this
    if(potentiallyUndefined){...do stuff...}
    
  • Like I said, it's a minor/negligible performance gain, so I don't pass in window. Besides, how much of my code uses window anyway?

\$\endgroup\$
1
0
\$\begingroup\$

There is only one positive result that I know : it lets minifiers replace window and undefined with shorter names.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.