我想了解jQuery插件语法


89

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

(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语法。所以这是我的问题清单:

  1. 如果将function($)...替换为变量,说“ the_function”,则语法如下所示:

     (the_function)( jQuery );

    什么是“(jQuery);” 在干嘛 围绕the_function的圆括号真的必要吗?他们为什么在那里?您是否可以提供另一段类似的代码?

  2. 它以function($)开头。因此,它正在创建一个函数,据我所知它将永远不会运行,并且已经定义了$参数。那里发生了什么事?

谢谢您的帮助!

Answers:


130
function(x){ 
    x...
}

只是一个没有名称的函数,它带有一个参数“ x”,并使用x执行操作。

您可以使用$(这是一个不太常用的变量名,但仍然合法)来代替“ x”(这是一个公共变量名)。

function($){ 
    $...
}

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

(function($){
    $....
})

要调用函数,请在()后面加上参数列表。例如,如果我们想调用此函数,并传入3作为值,$我们将这样做:

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

只是为了踢一下,让我们调用此函数并将jQuery作为变量传递:

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

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

为什么?

  • 因为每次您想使用jQuery做某事时都要编写jQuery很繁琐。

为什么不写$ = jQuery

  • 因为其他人可能将$定义为其他含义。这保证了$的其他任何含义都不会被此含义所掩盖。

20
很明显,但是缺少对引导解析器将函数定义作为表达式而不是语句进行解析的详细说明。这就是多余的括号。
Pointy 2010年

16
(function(){})()被称为IIFE(立即调用函数表达式)。让大家知道,你可以用其他符号来强制解析器处理函数作为表达式,比如+,!,-,~像这(和其他人): !function($){}(jQuery)。为了获得更多乐趣,您可以:~~+-!function($){}(jQuery)
大卫·默多克

(function($,win,doc){$ ....})(jQuery,window,document); 我也将添加此内容……这有助于我更好地理解。在这种和平的代码中,jQuery ---> $; 和窗口--->赢;然后文档---> doc ... :)谢谢...
Haranadh

我已经遇到了上面的列表中未涵盖恕我直言的代码示例:$(function(){.....}(jQuery)); (来自此处:docs.microsoft.com/en-us/aspnet/core/mvc/models/…)。在这里,我不了解$的用法。它似乎既不是jQuery选择器$(...)也不是'document ready'事件的简短语法,因为该函数不返回任何内容。我也似乎不是将函数视为表达式的前缀,因为它不在花括号内。此外,函数调用在花括号内,因此我们在声明。
sich

35

(function( $ ){

})( jQuery );

这是一种自执行匿名函数,该函数使用$in参数,因此您可以在函数内部使用它($)而不用使用它jQuery,而不必担心与其他库冲突,因为在其他库中也是如此$有特殊含义。在编写jQuery插件时,该模式特别有用。

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

(function(j){
  // can do something like 
  j.fn.function_name = function(x){};

})(jQuery);

这里j将自动追上最后指定的jQuery (jQuery)。或者,您可以完全省略参数,但是您将不得不在jQuery各处使用关键字,而$不用担心仍然会发生冲突。所以$包裹在简写参数中,以便您可以编写$而不是jQuery在该函数内部所有内容。

如果您甚至查看jQuery的源代码,您将看到所有内容都包裹在它们之间:

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

可以看出,带有参数的自执行匿名函数也是如此。创建一个window(和undefined)自变量,并将其与window底部的全局对象映射(window)。如今,这是一种流行的模式,并且几乎没有速度提高,因为window将从参数而不是window下面映射的全局对象开始查看。


$.fn是你创建新的功能(这也是一个对象)或插件本身让jQuery的包装插件在jQuery的对象$.fn对象,并使其可用。


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

JavaScript / jQuery闭包函数语法

您还可以查看这篇文章,以了解有关我编写的自执行功能的更多信息:

Javascript自执行功能


因此,如果我有一个名为my_object的对象,并且这样做:(function(mo){mo.doSomething()})(my_object),那么它将运行my_object.doSomething()吗?
伊桑(Ethan)2010年

3

基本的插件语法允许您使用$jQuery在插件的正文中进行引用,而无论$插件加载时的。这样可以防止与其他库(最著名的是Prototype)的命名冲突。

语法定义了一个函数,该函数接受一个称为参数的函数,$因此您可以$在函数主体中对其进行引用,然后立即调用该函数,并jQuery作为参数输入。

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


3

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

例:

(function(foo) {
    alert(foo);
}('BAR'));

BAR放入<script>块时这将发出警报。参数BAR将传递给调用自身的函数。

在您的代码中发生了相同的原理,将jQuery对象传递给函数,因此$可以肯定地引用jQuery对象。


1
我了解所有这些。我想知道的是为什么/如何使用括号语法创建自执行功能?这只是语言的功能吗?它是如何工作的?

2

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

(function(foo){

  foo.fn.myPlugin = function() {


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


    });

  };
})( jQuery );


2

这里的其他答案很好,但是有一个重要的问题尚未解决。你说:

因此,它正在创建一个函数,据我所知它将永远不会运行,并且已经定义了$参数。

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

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

调用时jQuery.noConflict(),全局变量$将设置回包含jQuery库之前的状态。这允许jQuery与也$用作全局变量的其他Javascript库一起使用。

如果您编写的插件依赖于$jQuery的别名,那么该插件将不适用于以noConflict模式运行的用户。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.