【问题标题】:I'd like to understand the jQuery plugin syntax我想了解 jQuery 插件语法
【发布时间】:2011-05-27 22:11:22
【问题描述】:

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. 它以函数 ($) 开头。所以它正在创建一个函数,据我所知,它永远不会运行,使用已经定义的 $ 参数?那里发生了什么?

感谢您的帮助!

【问题讨论】:

    标签: javascript jquery jquery-plugins


    【解决方案1】:

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

    所以它正在创建一个函数,据我所知,它永远不会运行,带有 $ 的参数,它已经定义了?

    无法保证全局变量$ 可用。默认情况下,jQuery 在全局范围内创建两个变量:$jQuery(其中两个是同一个对象的别名)。但是,jQuery can also be run in noConflict mode

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      它特别有用,因为其中许多模式在许多库中被广泛使用,但没有得到真正的解释。

      【讨论】:

        【解决方案3】:
        function(x){ 
            x...
        }
        

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

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

        function($){ 
            $...
        }
        

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

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

        要调用一个函数,你可以在它后面加上一个参数列表 ()。例如,如果我们想调用这个函数,传入 3 来获取 $ 的值,我们可以这样做:

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

        只是为了好玩,让我们调用这个函数并将 jQuery 作为变量传递:

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

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

        为什么?

        • 因为每次你想用 jQuery 做某事时都写 jQuery 很乏味。

        为什么不直接写$ = jQuery

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

        【讨论】:

        • 这很清楚,但它没有详细说明需要引导解析器将函数定义解析为表达式而不是语句。这就是 extra 括号的用途。
        • (function(){})() 被称为IIFE (Immediately Invoked Function Expression)。让大家知道您可以使用其他符号来强制解析器将函数视为表达式,例如+,!,-,~(和其他),如下所示:!function($){}(jQuery)。为了获得更多乐趣,您可以:~~+-!function($){}(jQuery)!
        • (function($, win, doc){ $.... })(jQuery, window, document);我也会添加这个......它帮助我更好地理解。在这种平静的代码中,jQuery ---> $;和窗口--->赢;然后文档--->文档... :) 谢谢...
        • 我遇到了一个代码示例,恕我直言,上面的列表没有涵盖:$(function () { ..... }(jQuery)); (取自这里:docs.microsoft.com/en-us/aspnet/core/mvc/models/…)。在这里,我不明白 $ 的用法。它似乎既不是 jQuery 选择器 $(...) 也不是“文档就绪”事件的简短语法,因为该函数不返回任何内容。我似乎也不是将函数视为表达式的前缀,因为它在大括号之外。此外,函数调用是在大括号内进行的,所以我们调用声明。
        【解决方案4】:

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

        这是在参数中使用$ 的自执行匿名函数,因此您可以在该函数中使用它($)而不是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 closure function syntax

        你也可以看看这篇文章来了解更多关于我写的自执行函数:

        Javascript Self-executing Functions

        【讨论】:

        • 所以如果我有一个名为 my_object 的对象,并且这样做:(function(mo){mo.doSomething()})(my_object),那么它会运行 my_object.doSomething()?跨度>
        【解决方案5】:

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

        例子:

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

        这将在放入 &lt;script&gt; 块时提醒 BAR。参数BAR 被传递给调用自身的函数。

        同样的原理发生在你的代码中,jQuery 对象被传递给函数,所以$ 肯定会引用 jQuery 对象。

        【讨论】:

        • 我明白这一切。我想知道的是括号语法为什么/如何工作以创建自执行函数?这只是语言的一个特点吗?它是如何工作的?
        【解决方案6】:

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

        (function(foo){
        
          foo.fn.myPlugin = function() {
        
        
            this.fadeIn('normal', function(){
        
        
            });
        
          };
        })( jQuery );
        

        【讨论】:

          【解决方案7】:

          基本插件语法允许您在插件主体中使用$ 来引用jQuery,无论加载插件时$ 的标识如何。这可以防止与其他库发生命名冲突,尤其是 Prototype。

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

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

          【讨论】:

            猜你喜欢
            • 2013-10-09
            • 2017-01-22
            • 1970-01-01
            • 2015-09-18
            • 2011-01-08
            • 2020-02-08
            • 1970-01-01
            • 2011-01-28
            • 1970-01-01
            相关资源
            最近更新 更多