What does (function($) {})(jQuery); mean?

2018-12-31 12:10发布

问题:

I am just starting out with writing jQuery plugins. I wrote three small plugins but I have been simply copying the line into all my plugins without actually knowing what it means. Can someone tell me a little more about these? Perhaps an explanation will come in handy someday when writing a framework :)

What does this do? (I know it extends jQuery somehow but is there anything else interesting to know about this)

(function($) {

})(jQuery);

What is the difference between the following two ways of writing a plugin:

Type 1:

(function($) {
    $.fn.jPluginName = {

        },

        $.fn.jPluginName.defaults = {

        }
})(jQuery);

Type 2:

(function($) {
    $.jPluginName = {

        }
})(jQuery);

Type 3:

(function($){

    //Attach this new method to jQuery
    $.fn.extend({ 

        var defaults = {  
        }  

        var options =  $.extend(defaults, options);  

        //This is where you write your plugin\'s name
        pluginname: function() {

            //Iterate over the current set of matched elements
            return this.each(function() {

                //code to be inserted here

            });
        }
    }); 
})(jQuery);

I could be way off here and maybe all mean the same thing. I am confused. In some cases, this doesn\'t seem to be working in a plugin that I was writing using Type 1. So far, Type 3 seems the most elegant to me but I\'d like to know about the others as well.

回答1:

Firstly, a code block that looks like (function(){})() is merely a function that is executed in place. Let\'s break it down a little.

1. (
2.    function(){}
3. )
4. ()

Line 2 is a plain function, wrapped in parenthesis to tell the runtime to return the function to the parent scope, once it\'s returned the function is executed using line 4, maybe reading through these steps will help

1. function(){ .. }
2. (1)
3. 2()

You can see that 1 is the declaration, 2 is returning the function and 3 is just executing the function.

An example of how it would be used.

(function(doc){

   doc.location = \'/\';

})(document);//This is passed into the function above

As for the other questions about the plugins:

Type 1: This is not a actually a plugin, it\'s an object passed as a function, as plugins tend to be functions.

Type 2: This is again not a plugin as it does not extend the $.fn object. It\'s just an extenstion of the jQuery core, although the outcome is the same. This is if you want to add traversing functions such as toArray and so on.

Type 3: This is the best method to add a plugin, the extended prototype of jQuery takes an object holding your plugin name and function and adds it to the plugin library for you.



回答2:

At the most basic level, something of the form (function(){...})() is a function literal that is executed immediately. What this means is that you have defined a function and you are calling it immediately.

This form is useful for information hiding and encapsulation since anything you define inside that function remains local to that function and inaccessible from the outside world (unless you specifically expose it - usually via a returned object literal).

A variation of this basic form is what you see in jQuery plugins (or in this module pattern in general). Hence:

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

Which means you\'re passing in a reference to the actual jQuery object, but it\'s known as $ within the scope of the function literal.

Type 1 isn\'t really a plugin. You\'re simply assigning an object literal to jQuery.fn. Typically you assign a function to jQuery.fn as plugins are usually just functions.

Type 2 is similar to Type 1; you aren\'t really creating a plugin here. You\'re simply adding an object literal to jQuery.fn.

Type 3 is a plugin, but it\'s not the best or easiest way to create one.

To understand more about this, take a look at this similar question and answer. Also, this page goes into some detail about authoring plugins.



回答3:

A little help:

// an anonymous function
  
(function () { console.log(\'allo\') });

// a self invoked anonymous function

(function () { console.log(\'allo\') })();
  
// a self invoked anonymous function with a parameter called \"$\"
  
var jQuery = \'I\\\'m not jQuery.\';

(function ($) { console.log($) })(jQuery);



回答4:

Type 3, in order to work would have to look like this:

(function($){
    //Attach this new method to jQuery
    $.fn.extend({     
        //This is where you write your plugin\'s name
        \'pluginname\': function(_options) {
            // Put defaults inline, no need for another variable...
            var options =  $.extend({
                \'defaults\': \"go here...\"
            }, _options);

            //Iterate over the current set of matched elements
            return this.each(function() {

                //code to be inserted here

            });
        }
    }); 
})(jQuery);

I am unsure why someone would use extend over just directly setting the property in the jQuery prototype, it is doing the same exact thing only in more operations and more clutter.



回答5:

Just small addition to explanation

This structure (function() {})(); is called IIFE (Immediately Invoked Function Expression), it will be executed immediately, when the interpreter will reach this line. So when you\'re writing these rows:

(function($) {
  // do something
})(jQuery);

it means, that the interpreter will invoke this function immediately, and will pass jQuery as parameter, which will be used inside the function as $.



回答6:

Actually, this example helped me to understand what does (function($) {})(jQuery); mean?

Consider this:

// Clousure declaration (aka anonymous function)
var $f = function (x) { return x*x; };
// And use of it
console.log($f(2)); // Gives: 4

// An inline version (immediately invoked)
console.log((function (x) { return x*x; })(2)); // Gives: 4

And now:

jQuery is a variable holding jQuery object.
$ is a variable name like any other (a, $b, a$b etc. and it doesn\'t have any special meaning like in PHP).

var $f = function ($) { return $*$; };
var jQuery = 2;
console.log($f(jQuery)); // Gives: 4

// An inline version
console.log((function ($) { return $*$; })(jQuery)); // Gives: 4