【问题标题】:Javascript wrapping code inside anonymous functionJavascript在匿名函数中包装代码
【发布时间】:2013-10-26 18:51:14
【问题描述】:

我需要帮助来理解这种 jQuery 插件创作模式。有人可以帮我解释一下这段简单的代码吗?

(function($) { /* Code here */ })(jQuery);

我知道这是为了避免与使用相同 $ 字符的不同插件发生冲突,但不知何故我无法理解它是如何工作的。参数$与解析到的jQuery对象有什么关系?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    让我们分解一下:

    (function($) { /* Code here */ })(jQuery);
    

    首先,构造:

    (function() {})();
    

    创建一个立即执行的函数表达式(通常称为 IIFE)。这是一个立即执行而不是现在定义但稍后调用的函数。它本质上是一个匿名(未命名)函数,被定义然后立即执行。

    然后,像这样将 jQuery 传递给它:

    (function() {})(jQuery);
    

    将 jQuery 作为第一个参数传递给立即执行的函数。然后,将第一个参数命名为 $ 将函数内部的符号定义为与传递的第一个参数相对应。

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

    展开形式如下:

    (function($) {
        // you can use $ here to refer to jQuery
    })(jQuery);
    

    对于 jQuery 插件作者来说,这有一些好处:

    1. IIFE 创建了一个局部函数上下文,因此您可以拥有对插件来说是“全局”的变量,但实际上不是全局变量,因此不会污染或与实际的全局变量命名空间发生冲突。

    2. 您可以为 jQuery 使用 $ 进行编程,无论宿主程序实际上是否具有为 jQuery 定义的内容,因为您已在函数中本地定义了 $

    【讨论】:

    • 谢谢,伙计。很简单。我被卡住了,因为我纠结于那个 jquery 会包装这个函数,并且这个包装函数使用的 jQuery 库中会有一个预定义的 jquery 变量。
    • 你解释得很好!
    【解决方案2】:

    你所拥有的是这样的简写:

    function anonymous_function($) {
        // Code here
    };
    anonymous_function(jQuery);
    

    如您所见,它允许将$ 符号用作对函数内部jQuery 对象的引用。

    【讨论】:

    • 这更有意义。它有助于澄清 jfriend00 对我的回答。谢谢!
    【解决方案3】:

    JavaScript 中的函数可以be either a statement or an expression。当您使用函数表达式时,您可以像传递任何其他值一样传递它:

    > console.log(function() { 1 + 1; });
    > (function() {}) && doExpensiveWork();
    // etc.
    

    使用函数表达式可以做的事情之一就是立即调用它。在这种情况下,该函数称为an immediately invoked function expression (or IIFE for short)

    > (function() { console.log("IIFE running"); })();
    IIFE running
    

    这与创建函数并分两步调用它是一样的:

    > var notAnIIFE = function() { console.log("running"); };
    > notAnIIFE();
    running
    

    函数表达式当然可以接受参数:

    > var someFunction = function(x, y) { return x + y; };
    > var seven = someFunction(3, 4);
    > seven
    7
    

    所以IIFE 也可以使用参数调用:

    > var seven = (function(x, y) { return x + y; })(3, 4);
    > seven
    7
    

    如果是这样的调用:

    (function($) { /* do work with $ */ })(jQuery);
    

    绑定到名称jQuery 的值作为参数$ 传递给函数表达式。这类似于执行以下操作:

    var initializePlugin = function($) {
        /* do work with $ */
    };
    initializePlugin(jQuery);
    

    但它不会在父命名空间中留下任何痕迹(而在我们的第二个示例中,我们的 initializePlugin 名称在我们完成插件设置后留下)。

    【讨论】:

      【解决方案4】:

      javascript 中的函数创建了一个作用域,它不仅与$ 变量有关,还与函数的本地变量有关。并且给定$参数,它成为函数的本地并且可以安全使用,参考jQuery

      【讨论】:

        【解决方案5】:

        jfriend00 的回答+1。

        但是在页面中包含 jQuery 会覆盖全局符号 jQuery 和 $(请参阅 jQuery.js line 9579),这可能会导致与定义全局 $ 的其他库发生冲突。

        因此更进一步,也可以阻止全球 $ 冲突:

        (function($) {
            // you can use $ here to refer to jQuery
        })(jQuery.noConflict());
        

        如下所示:

        <script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
        <script>
        (function($) {
           console.log('want $ to be jQuery here so want true: ' + ($ === jQuery));
        })(jQuery.noConflict());
        console.log('do not want $ to be jQuery here so want false: ' + ($ === jQuery));
        </script>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-01-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-16
          相关资源
          最近更新 更多