【问题标题】:start javascript code with $(function, etc用 $(function 等启动 javascript 代码
【发布时间】:2012-08-14 01:58:27
【问题描述】:

我正在研究来自http://todomvc.com/ 的 Backbone 和待办事项示例应用程序 我注意到文件中有 3 种启动代码的方法:

$(function() {
 // code here
});

$(function( $ ) {
 // code here
});

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

我不明白这些差异以及何时应该使用其中一个。

我还看到一些人使用它来启动他们的代码:

$(document).ready(function(){
  // code here
});

据我所见,这就是完整的写法吧?

以更一般的方式,我是否应该始终将我的 javascript 代码包含在每个文件中的类似内容中?

感谢您的建议。

【问题讨论】:

标签: javascript jquery backbone.js


【解决方案1】:

我想从意识到$ = jQuery 开始是有意义的。在阅读匿名函数中的命名空间时,下面的目的会更有意义。但本质上,您可以使用其中任何一个。如果他们使用多个库,并且希望 $ 被另一个使用,那么他们将使用 jQuery() 而不是 $()

$(document).ready(function(){
    // Here we have jQuery(document) firing off the ready event
    // which executes once the DOM has been created in 
    // order to ensure that elements you are trying to manipulate exist.
});

​$(function () {
    // Short-hand version of $(document).ready(function () { });
});

More information on Document.ready()

$ 放在括号内可确保 jQuery $ 别名(您可以放心,它总是以这种方式表示 jQuery)。

$(function ($) { /* code here : $ always means jQuery now */ }); 

最后你有一个IIFE(立即调用函数表达式) - IIFE explanation

(function (myNameSpace, $) {
    // This is an anonymous function - it is ran instantly
    // Usually used for namespaces / etc
    // This creates a scope/wrapper/closure around everything inside of it
}(window.myNameSpace, jQuery));

顶部的 $(与底部的 jQuery 匹配)表示 $(美元符号)代表命名空间范围内的 jQuery。 这样做是为了确保其他库不会与开发人员的内容发生冲突 打算/想要与 $ 一起使用。

(function (myNameSpace, $) {
    // Now because of all of this scope/wrapper/closure awesome...
    // you can create -INTERNAL- variables (sort of like Private variables from other langs) 
    // this variable cannot be accessed outside the namespace unless it is returned / exposed

    var internalVariable = '123'; // Internal

    // Even Internal functions!
    function privateFunction () {
        console.log('this is private!');
    }

    // --------------------------------------------------------
    // Public -method- of nameSpace exposing a private variable
    // Notice we're using the myNameSpace object we exposed at the top/bottom

    myNameSpace.nameSpaceMethod = function () {
        privateFunction(); // we can call the private function only inside of the namespace
        return internalVariable; // now we could get this variable
    };
}(window.myNameSpace, jQuery)); // notice these mirror the above arguments in the anon function

More information on anonymous functions

现在,如果我们在命名空间之外,我们可以看到这些内部/公共方法和变量是如何受到影响的:

// This will come up undefined
alert(internalVariable);

// This will trigger a -method- of the myNameSpace namespace - and alert "123"
// Showcasing how we access a Public method - which itself has access to the internal variable
// and exposes it to us!
alert(myNameSpace.nameSpaceMethod());
​

【讨论】:

    【解决方案2】:
    1. $(document).ready(function(){}) 确保您的代码在准备好的 DOM 上运行,以便您可以访问 DOM。您可以在jQuery's documentation 中阅读更多相关信息。

    2. $(function(){}) 只是 #1 的别名。此处的任何代码都将等待 DOM 就绪 (see the docs)。

    3. $(function($){}) 等价于#1 和#2,只有你在local scope 中获得了对 jQuery 的干净引用(参见下面的注释)。您同样可以将$ 传递给#1 中的函数,它会做同样的事情(创建对jQuery 的本地引用)。

    4. (function(){}()) 只是一个self-executing-anonymous-function,用于创建一个新的闭包。

    请注意,这些都不是 Backbone 特有的。前 3 个是特定于 jQuery 的,而 #4 只是 vanilla JavaScript。


    注意:要了解上面#3 中发生了什么,请记住$jQuery 的别名。然而,jQuery 并不是唯一使用$ 变量的库。由于$ 可能会被其他人覆盖,因此您要确保在您的范围内,$ 将始终引用 jQuery - 因此$ 参数。


    最后基本上归结为以下2个选项:

    1. 如果你的 JavaScript 是在 head 中加载的,你必须等待文档准备好,所以使用这个:

      jQuery(function($) {
          // Your code goes here.
          // Use the $ in peace...
      });
      
    2. 如果您将 JavaScript 加载到文档底部(在结束正文标记之前 - which you should definitely be doing),则无需等待文档准备好(因为在解析器到达您的脚本),SEAF(又名IIFE)就足够了:

      (function($) {
          // Use the $ in peace...
      }(jQuery));
      

    P.S.要更好地理解闭包和作用域,请参阅JS101: A Brief Lesson on Scope

    【讨论】:

    • 只是为了避免混淆(和某些愤怒)自我执行匿名函数并没有真正执行自己..他们已经创造了这个但实际上是Immediately Invoked Functions并且在发布此消息后,我立即看到了关于 (A.K.A IIFE) 所以 nvm 的小脚注:P 有趣的是,我们都链接到同一篇文章。
    • @rlemon - 虽然我同意 Cowboy (Ben Alman) 的观点,即 immediatly-invoked-function-expression 是更准确的术语,但 self-executing-anonymous- function 已成为引用它们的标准方式。我们都链接到同一篇文章,因为那是 IIFE 名称的来源。附言不管你怎么称呼他们,那篇文章都值得一读。它有一些关于这些函数表达式的重要信息。
    • 哦,我已经读过了,我个人不在乎我们如何称呼它们,只要人们知道它们的功能以及为什么使用它们。我只是在做我的尽职调查并将其链接起来:P 但这一切都不是:P 你已经拥有了 :) 我喜欢 IIFE 只是因为它更准确,而 SEAF 是一个丑陋的首字母缩略词。
    • @rlemon - 我不会说 SEAF 是一个丑陋的首字母缩略词。但是当谈到他们的发音时......来吧!没有什么比“不确定”更好的了:P
    • @JosephSilber:您是否意识到您使用包含按编号引用的编号列表会使阅读变得混乱?你说2. ... is just an alias to #1.3. ... is equivalent to #2 ... 这使得$(document).ready(function(){})$(function(){})$(function($){}) 看起来都差不多。如果其中一些数字指的是 OP 问题中未编号的示例,那么您的答案肯定会从一些澄清中受益。 - 可能是我很困惑!无论哪种方式,我确信可以澄清以排除错误的解释
    【解决方案3】:

    这两个:

    $(function() {
     // code here
    });
    
    $(document).ready(function(){
      // code here
    });
    

    是直接等价的,它们都是在文档加载时启动一些 jQuery 的方式。前者只是后者的较短版本。

    这个:

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

    只是一个零参数的作用域函数,它会立即以零参数调用。

    【讨论】:

      猜你喜欢
      • 2018-03-15
      • 2011-01-12
      • 2014-04-24
      • 2012-08-29
      • 2018-09-10
      • 1970-01-01
      • 2018-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多