关于javascript:我想了解jQuery插件语法

I'd like to understand the jQuery plugin syntax

jQuery站点列出了jQuery的基本插件语法,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
(function( $ ){    
  $.fn.myPlugin = function() {      
    // there's no need to do $(this) because
    //"this" is already a jquery object

    // $(this) would be the same as $($('#element'));

    this.fadeIn('normal', function(){    
      // the this keyword is a DOM element    
    });    
  };
})( jQuery );

我只是想从Javascript的角度理解那里发生了什么,因为它看起来不像我之前看过JS所做的任何语法。 所以这是我的问题列表:

  • 如果用函数替换函数($)...,比如"the_function",语法如下所示:

    1
     (the_function)( jQuery );

    什么是"(jQuery);"在做什么? 围绕the_function的括号是否真的有必要? 他们为什么在那里? 你能提供的另一段代码是否类似?

  • 它以函数($)开头。 所以它创建了一个函数,据我所知,它永远不会被运行,参数为$,已经定义了? 那里发生了什么?

  • 谢谢您的帮助!


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

    只是一个没有名字的函数,它接受一个参数"x",并用x做事。

    而不是'x',这是一个常见的变量名,你可以使用$,这是一个不常见的变量名,但仍然合法。

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

    我将它放在括号中以确保它作为表达式解析:

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

    要调用一个函数,可以在其后面添加一个参数列表。例如,如果我们想调用此函数传入3作为$的值,我们将这样做:

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

    只是为了踢,让我们调用这个函数并传入jQuery作为变量:

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

    这将创建一个新函数,它接受一个参数然后调用该函数,并传入jQuery作为值。

    为什么?

    • 因为每次想要使用jQuery做jQuery时编写jQuery都很乏味。

    为什么不写$ = jQuery

    • 因为其他人可能已将$定义为其他内容。这保证了$的任何其他含义都被这个暗示了。


    1
    2
    3
    (function( $ ){

    })( jQuery );

    这是一个自执行的匿名函数,它在参数中使用$,这样你就可以在函数中使用它($)而不是jQuery而不用担心与其他库发生冲突,因为在其他库中也是如此$有特殊意义。在编写jQuery插件时,该模式特别有用。

    您可以在那里写任何字符而不是$

    1
    2
    3
    4
    5
    (function(j){
      // can do something like
      j.fn.function_name = function(x){};

    })(jQuery);

    这里j将自动捕获末尾(jQuery)指定的jQuery。或者你可以完全忽略参数,但是你必须使用jQuery关键字而不是$而不用担心碰撞。所以$包含在短手的参数中,这样你就可以在函数内部写入$而不是jQuery

    如果您甚至查看jQuery的源代码,您将看到所有内容都包含在:

    1
    2
    3
    (function( window, undefined ) {
      // jQuery code
    })(window);

    这也是可以看到带参数的自执行匿名函数。创建window(和undefined)参数,并使用底部(window)的全局window对象进行映射。这是现在流行的模式并且几乎没有速度增益,因为这里将从参数而不是在下面映射的全局window对象中查看window

    $.fn是jQuery的对象,您可以在其中创建新函数(也是对象)或插件本身,以便jQuery将您的插件包装在其$.fn对象中并使其可用。

    有趣的是,我在这里回答了类似的问题:

    JavaScript / jQuery闭包函数语法

    您还可以查看本文以了解有关我编写的自执行函数的更多信息:

    Javascript自执行功能


    你正在那里处理一个自我调用的匿名函数。这就像在最佳实践中将jQuery插件包装在这样的函数中,以确保$符号绑定到jQuery对象。

    例:

    1
    2
    3
    (function(foo) {
        alert(foo);
    }('BAR'));

    当放入块时,这会提醒BAR。参数BAR被传递给调用自身的函数。

    在您的代码中发生了相同的原则,jQuery对象被传递给函数,因此$将引用jQuery对象。


    基本的插件语法允许您使用$来引用插件正文中的jQuery,无论插件加载时$的标识如何。这可以防止与其他库的命名冲突,最明显的是Prototype。

    语法定义了一个函数,它接受一个名为$的参数,因此你可以在函数体中将它称为$,然后立即调用该函数,将jQuery作为参数。

    这也有助于不污染全局命名空间(因此声明插件体中的var myvar = 123;不会突然定义window.myvar),但主要的表面目的是允许您使用$,其中$可能已经重新定义。


    这里的其他答案都很棒,但有一个重要的问题没有得到解决。你说:

    So it's creating a function, that as far as I can tell will never be run, with the parameter of $, which is already defined?

    无法保证全局变量$可用。默认情况下,jQuery在全局范围内创建两个变量:$jQuery(其中两个是同一对象的别名)。但是,jQuery也可以在noConflict模式下运行:

    1
    2
    3
    <script type="text/javascript" src="jquery.js">
    <script type="text/javascript">
      jQuery.noConflict();

    当您调用jQuery.noConflict()时,全局变量$将被设置回包含jQuery库之前的任何内容。这允许jQuery与其他使用$作为全局变量的Javascript库一起使用。

    如果你编写了一个依赖于$作为jQuery别名的插件,那么你的插件对于在noConflict模式下运行的用户不起作用。

    正如其他人已经解释的那样,您发布的代码会创建一个立即调用的匿名函数。然后将全局变量jQuery传递给此匿名函数,该函数在函数中安全地别名为局部变量$


    为了找到这个和其他现代javascript技巧和常见做法的清晰解释,我建议阅读Javascript Garden。

    http://bonsaiden.github.com/JavaScript-Garden/

    它特别有用,因为许多这些模式在许多库中被广泛使用,但没有真正解释过。


    最后的jQuery将自己(jQuery)传递给函数,以便您可以在插件中使用$符号。你也可以这样做

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    (function(foo){

      foo.fn.myPlugin = function() {


        this.fadeIn('normal', function(){


        });

      };
    })( jQuery );