4

So far I've learned the benefits of using this function (is it wrapping?)

So, it almost acts like namespaces. Suppose we have:

( function() {

    function foo(){
        alert(true);
    }

    foo(); //alerts true

})();


( function() {

    function foo(){ //the same title of the function as above
        alert("another call of foo");
    }

    foo(); //alerts, ok.

})();

Also I've noticed it can access public vars, like this:

var __foo__ = 'bar';

( function() {

    alert(__foo__); //alerts bar

})();

I have several questions regarding this approach

What I've tried:

  1. Use Bing for tutorials (I' found them, but many of them don't answer my questions)
  2. Play with passing objects into the body
  3. Find the answer here

But, I'm still beating my head against the wall

So the questions are:

I've seen people pass objects as params, but when DOES it make sense? For example, what does it mean?

  1. ( function(window) {
    
    
    })(document);
    
  2. I saw smth like this in Jquery UI Lib

    ( function($) {
        //some code of widget goes here
    })(Jquery);
    

This makes inner code visible outside the function, right? (not sure) Why, this is because we can access the object (say we have "modal" widget), simply by calling it,

like:

$(function(){

    $("#some_div").modal(); //here it's object the we got from the function
});

And the second question is: How does it work.

Yang
  • 8,580
  • 8
  • 33
  • 58
  • What's the question? Are you having an issue with an implementation of `(function(){})()`, as the title suggests? Or are you just asking how it works and when to use it? – MrOBrian Aug 15 '12 at 19:01
  • @MrOBrian Well, I have the both issues. – Yang Aug 15 '12 at 19:02

6 Answers6

2

I've seen people pass objects as params, but when DOES it make sense? For example, what does it mean?

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

The language does not treat parameters to immediately called functions differently than parameters to other functions.

It makes sense to use a parameter whenever you want a local name in your function body for an input. In this case it's a bit confusing since window and document are likely to be confused.


( function($) {
     //some code of widget goes here
})(Jquery);

This makes inner code visible outside the function, right? (not sure) Why, this is because we can access the object (say we have "modal" widget), simply by calling it,

No. It does not by itself make any code visible outside the widget. It's just a parameter definition which provides a new&local name for a global variable.

What makes inner code visible outside is attaching it to an external object as in

$.exportedProperty = localVariable;

which is a common convention in jQuery code.

Community
  • 1
  • 1
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
1

on your first question, I dont think you seen window and document but something more like:

(function(doc) {
    var fubar = doc.getElementById("fubar"); // === document.getElementById("fubar")
})(document);

you have a self-invoking function (or closure) with arguments like any function:

var b = function(str) { alert(str); }
b('hi there') //alert('hi there');

the same thing is it with the code above, but we are just calling the method at once we created it.

the other code you have:

( function($) {
    //some code of widget goes here
})(Jquery);

is to reserve the $variable inside the metod to refer to the jQuery object, this is very handy if you have more frameworks or replaced the $ object with something else, everything inside that method with an $ will refer to the jQuery object and nothing else(if you don´t replace it inside your code).

the code:

$(function(){
    $("#some_div").modal(); //here it's object the we got from the function
});

is calling jQuery and its a shortcut for $(document).ready

it will call the method:

function(){
    $("#some_div").modal(); //here it's object the we got from the function
}

as soon as the DOM is ready

voigtan
  • 8,953
  • 2
  • 29
  • 30
1

The pattern is called a closure. It makes sense to use when a module or function:

  1. wants to avoid polluting globally-scoped variables
  2. wants to avoid use globally-scoped variables and avoid other code polluting them

For an example of each, first take this pattern:

(function(window) {
    // ...
})(window);

Everything inside the closure will be able to use window as if it were a local variable.

Next, take the same pattern using the JQuery symbol:

(function($) {
    // ...
})($);

If you have some code that relies on a symbol/namespace like $, but another module reassigns that, it can screw up your code. Using this pattern avoids this by allowing you to inject the symbol into a closure.

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
1

Whenever you pass an argument to that wrapping function it's so that you won't mess up with any other libraries or global variables that may be present in your application.

For example as you may know jQuery uses $ as a symbol for calling itself, and you may also have another library, that will also use $ for calling itselt, under this condition you may have trouble referencing your libraries. so you would solve it like this:

(function($){
// here you're accessing jQuery's functions
$('#anything').css('color','red');
})(jQuery);

(function($){
    // and in here you would be accessing the other library
    $.('#anything').method();
})(otherLibrary);

This is specially useful when you're making jQuery or any other kind of library plugins.

Isaac Gonzalez
  • 1,734
  • 1
  • 16
  • 22
1

What it does is allow you to use the $ variable inside your function in place of the jQuery variable, even if the $ variable is defined as something else outside your function.

As an example, if you're using both jQuery and Prototype, you can use jQuery.noConflict() to ensure that Prototype's $ is still accessible in the global namespace, but inside your own function you can use $ to refer to jQuery.

mdarwi
  • 913
  • 4
  • 9
1

There are mainly 2 purposes of passing in the window and document objects such as seen below

(function(window, document){
   // code
}(window, document);
  1. Javascript can access local variables faster than global variables. This pattern in effect makes the names window and document local variables rather than global, thus making your script slightly faster.
  2. Making these names local variables has another benefit: minifiers can rename them. So if you minify the above script, the local version of window might get renamed to a and document might get renamed to b, thus making the minified script smaller. If you were to reference them as globals, these renamings are impossible because that would break your script.

For more info, checkout these awesome videos

  1. http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/
  2. http://paulirish.com/2011/11-more-things-i-learned-from-the-jquery-source/
airportyh
  • 21,948
  • 13
  • 58
  • 72