关于javascript:什么(function($){})(jQuery);

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

我刚开始写jquery插件。我写了三个小插件,但我只是把这行代码复制到我所有的插件中,却不知道它的含义。有人能多告诉我一点吗?也许有一天,当编写一个框架时,一个解释会很有用。

这是做什么的?(我知道它以某种方式扩展了jquery,但是否还有其他有趣的事情要了解)

1
2
3
(function($) {

})(jQuery);

以下两种编写插件的方法有什么区别:

类型1:

1
2
3
4
5
6
7
8
9
(function($) {
    $.fn.jPluginName = {

        },

        $.fn.jPluginName.defaults = {

        }
})(jQuery);

类型2:

1
2
3
4
5
(function($) {
    $.jPluginName = {

        }
})(jQuery);

类型3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(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);

我可能离这里很远,也许所有的意思都一样。我很困惑。在某些情况下,这似乎在我使用类型1编写的插件中不起作用。到目前为止,3型对我来说似乎是最优雅的,但我也想知道其他的。


首先,一个看起来像(function(){})()的代码块仅仅是一个就地执行的函数。让我们把它分解一下。

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

第2行是一个普通的函数,用括号括起来,告诉运行时将函数返回到父作用域,一旦函数返回,就使用第4行执行函数,也许阅读这些步骤会有所帮助。

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

您可以看到1是声明,2返回函数,3只是执行函数。

如何使用它的示例。

1
2
3
4
5
(function(doc){

   doc.location = '/';

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

关于插件的其他问题:

类型1:这实际上不是一个插件,而是一个作为函数传递的对象,因为插件往往是函数。

类型2:这又不是插件,因为它不扩展$.fn对象。它只是jquery核心的一个扩展,尽管结果是相同的。这是如果您想添加遍历函数,如toarray等。

类型3:这是添加插件的最佳方法,jquery的扩展原型获取一个包含插件名称和函数的对象,并将其添加到插件库中。


在最基本的层次上,(function(){...})()的形式是一个立即执行的函数文本。这意味着您已经定义了一个函数,并且正在立即调用它。

此表单对于信息隐藏和封装很有用,因为您在该函数内定义的任何内容都保持该函数的局部性,并且在外部世界中无法访问(除非您特别公开它——通常通过返回的对象文本)。

这个基本形式的一个变体就是您在jquery插件中看到的(或者通常在这个模块模式中看到的)。因此:

1
2
3
(function($) {
  ...
})(jQuery);

这意味着您要传递一个对实际jQuery对象的引用,但它在函数文本的范围内称为$

类型1不是真正的插件。您只需将对象文本分配给jQuery.fn。通常,您将一个函数分配给jQuery.fn,因为插件通常只是函数。

类型2类似于类型1;您实际上并没有在这里创建插件。您只是在jQuery.fn中添加一个对象文字。

类型3是一个插件,但它不是创建插件的最佳或最简单的方法。

要了解更多有关这方面的信息,请看一下类似的问题和答案。此外,本页还详细介绍了如何编写插件。


一点帮助:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 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);


只是解释的一小部分

此结构(function() {})();称为iife(立即调用的函数表达式),当解释器到达此行时,将立即执行。所以当你写这些行时:

1
2
3
(function($) {
  // do something
})(jQuery);

这意味着解释器将立即调用该函数,并将jQuery作为参数传递,该参数将在函数内用作$


类型3,为了工作,必须如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(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);

我不确定为什么有人会直接使用扩展来设置jquery原型中的属性,它只在更多的操作和更多的混乱中做同样的事情。


实际上,这个例子帮助我理解了(function($) {})(jQuery);的意思是什么?考虑一下:

1
2
3
4
5
6
7
// 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

现在:

jQuery是一个保存jquery对象的变量。$是一个变量名,与其他变量一样(a$ba$b等,没有php中的特殊含义。

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

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