【问题标题】:Javascript: why does jQuery do this: (function(){ ...});, and how does it work?Javascript:为什么 jQuery 这样做:(function(){ ...});,它是如何工作的?
【发布时间】:2009-12-17 23:21:53
【问题描述】:

编辑:我认为 我正在查看的 jQuery 源代码是这样的:

(function(){
    var bunchOfVariables = 7;
    jQuery = " ....."; 
    //....
});

我错了。忽略这个问题。


我不明白那是做什么的。有人可以解释一下吗?

这是jQuery-1.3.2.js 的第一行。

它似乎定义了一个匿名函数,而不是执行它。函数去哪儿了?它是如何运行的?

如果我在测试脚本中使用这样的代码,它永远不会被调用。另一方面,如果我用开闭括号跟随它,那么它就会被调用:

// never gets called
(function(){
    say("hello");
});
// gets called
(function(){
    say("buon giorno");
})();

【问题讨论】:

  • 在您的第一个示例中,是否将其分配给变量?如果不是,我会假设它只是开发人员未使用的残余。
  • 如果函数没有名称并且没有被调用(即函数后面没有()),那么似乎代码被忽略了。介意您提及您正在查看的来源吗?
  • 该代码的来源: jquery-1.3.2.js 。 code.google.com/p/jqueryjs/downloads/…
  • 我同意布赖恩雷维斯的观点。也许开发人员使用了一个未命名的、未调用的闭包来故意“注释”掉代码。在整个内容周围使用多行注释可能会与其他包含的多行 cmets 冲突。
  • 呃,你是说 jQuery 1.3.2 的源代码可以做到这一点?什么行号?

标签: javascript jquery class-design


【解决方案1】:

jQuery 源代码的最后一行是

})();

括号表示正在调用该函数。

【讨论】:

  • 我的错 - 我的paren-matching在编辑器中关闭了,不知怎的,我以为是前者,其实不是。
【解决方案2】:

它实际上在做的是:

(function(){
    var bunchOfVariables = 7;
    jQuery = window.jQuery = window.$ = ...
    //....
})();

注意末尾的“()”,它运行整个代码块。这样做的原因是为了防止所有这些“bunchOfVariables”最终进入“全局”(阅读:窗口)范围。

jQuery(和 $),然而,因为这条线,最终在全球范围内可用:

jQuery = window.jQuery = window.$ = ...

请记住,在 DOM 世界中,“全局”表示“窗口的成员变量”。

【讨论】:

  • 啊,不知何故,我的编辑器并没有完全正确地匹配卷曲和括号。我原以为第一行匹配的紧卷曲没有紧跟 )(); .
【解决方案3】:

这是一个避免泄漏全局符号的闭包。您定义一个函数并立即执行它。

(function(){
  // some code
})();

这个模式的一个常见版本将'$'符号显式绑定到jQuery,以防jQuery.noConflict()被调用:

(function($){
  // some code here, '$' is bound to jQuery
})(jQuery);

【讨论】:

    【解决方案4】:
    (function() { /* ... */ })();
    

    这种模式通常被称为“自执行匿名函数”。它定义了一个新的匿名函数(即function() { /* ... */ } 部分)并立即执行它(即最后的())。函数声明周围的额外括号并不是绝对必要的,但有助于使代码更清晰。

    现在为什么会有人想要这样做? JavaScript 中的每个函数都有自己的作用域。在其中声明的任何变量或函数都是该函数的本地变量,并且只能在其中访问。因此,假设您正在编写一个 jQuery 插件。也许您的插件需要大量变量和内部方法。如果你在一个自动执行的匿名函数中声明所有这些,你就可以避免用你所有的内部对象污染全局范围。

    【讨论】:

    • 这并不完全正确。如果要声明匿名函数,则需要“额外的括号”。如果你离开它们,你会得到一个错误。但是,如果将其分配给变量,则可以忽略它们。
    【解决方案5】:

    我想你可能弄错了。 jQuery 的第一行启动了一个自执行匿名函数。你确定你没有正确匹配大括号?

    【讨论】:

    • 是的,这正是我所做的。 . .
    【解决方案6】:

    jQuery 1.3.2(当前版本)按照这些思路定义了一个匿名函数,但确实执行了它;我怀疑你被他们在发布副本中的一些……异常缩进误导了。

    匿名函数的重点是提供范围。这称为“模块模式”。这是一个简化的例子

    (function() {
    
        function doSomething() {
            doSomethingElse();
        }
    
        function doSomethingElse() {
        }
    
        window.doSomething = doSomething;
    })();
    

    (虽然我通常不会这样做,但它类似于 jQuery 的做法。)

    现在有一个“公共”符号(doSomething,它是 window 的一个属性),它引用了 doSomething 函数。 doSomethingElse 函数可以从doSomething 访问,但没有其他地方。例如,它是私有范围的。

    【讨论】:

    • 我的编辑器,或者更准确地说是编辑模式,让我失望了。它弄错了paren-match,这就是让我相信anon函数没有被执行的原因。我当然错了。
    【解决方案7】:
    (function(){
    var bunchOfVariables = 7;
    jQuery = " ....."; 
    //....
    });
    

    实际上是在创建一个没有参数的新匿名函数,其中包含一些变量。但是你只是创建了一个实例而不是调用函数本身。

    想象一下,您想将一个函数存储到一个 var 中:

    var fn=function(parameter1, parameter2){..}
    

    fn 现在持有匿名函数的一个实例,要调用它你必须这样做

    fn(arg1, arg2).
    

    因此,使用 open close paren 时,您只是在调用函数,但没有任何参数。

    【讨论】:

    • 只是为了澄清-您答案中的第一个代码块实际上等效于注释掉的代码。函数的主体没有被执行。
    【解决方案8】:

    (function() { /* ... */ }) 不是“自执行匿名函数”,() 不仅仅是“代码的样子”,它们执行函数...

    【讨论】:

      猜你喜欢
      • 2012-01-08
      • 1970-01-01
      • 2014-03-18
      • 2010-12-17
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      • 1970-01-01
      相关资源
      最近更新 更多