29

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

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

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

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

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

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

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

从我所见,这是完整的写作方式,对吗?

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

谢谢你的建议。

4

3 回答 3

55
  1. $(document).ready(function(){})确保您的代码在准备好的 DOM 上运行,以便您可以访问 DOM。您可以在jQuery 的文档中阅读更多相关信息。

  2. $(function(){})只是#1 的别名。此处的任何代码都将等待 DOM 准备就绪(请参阅文档)。

  3. $(function($){})等效于#1 和#2,只有你在本地范围内获得对 jQuery 的干净引用(请参阅下面的注释)。你同样可以传入$#1 中的函数,它会做同样的事情(创建一个对 jQuery 的本地引用)。

  4. (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 加载到文档的底部(在结束 body 标记之前 -您绝对应该这样做),则无需等待文档准备好(因为在解析器到达您的脚本),一个SEAF(又名IIFE)就足够了:

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

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

于 2012-08-17T15:41:55.800 回答
18

我想通过意识到这一点开始是有意义的$ = 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 () { });
});

有关 Document.ready() 的更多信息

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

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

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

(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

有关匿名函数的更多信息

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

// 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());
​
于 2012-08-17T15:43:53.207 回答
2

这两个:

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

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

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

这个:

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

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

于 2012-08-17T15:42:27.633 回答