38

我正在研究 jQuery 最佳实践,发现Greg Franko 的这篇文章

通常,我会:

$("document").ready(function() {
    // The DOM is ready!
    // The rest of the code goes here
});

但文章建议使用:

// IIFE - Immediately Invoked Function Expression
(function($, window, document) {

    // The $ is now locally scoped 

    // Listen for the jQuery ready event on the document
    $(function() {

        // The DOM is ready!

    });

    // The rest of the code goes here!

}(window.jQuery, window, document));
// The global jQuery object is passed as a parameter

我可以看到那里的评论,但我无法弄清楚它到底在说什么。

那么,哪种方法更好,为什么?

我知道这两种方法都可以,但是第二种方法如何变得更好

4

9 回答 9

50

立即调用函数表达式 (IIFE)

IIFE 是一个理想的解决方案,用于在本地限定全局变量/属性并保护您的 JavaScript 代码库免受外部干扰(例如第三方库)。如果您正在编写将在许多不同环境中运行的 jQuery 代码(例如 jQuery 插件),那么使用 IIFE 对 jQuery 进行本地范围很重要,因为您不能假设每个人都使用 $ 来为 jQuery 取别名。以下是您的操作方法:

   // IIFE - Immediately Invoked Function Expression
  (function($, window, document) {
      // The $ is now locally scoped

      // The rest of your code goes here!

  }(window.jQuery, window, document));
  // The global jQuery object is passed as a parameter

如果您不喜欢滚动到源文件的底部来查看您传递给 IIFE 的全局变量/属性,您可以这样做:

   // IIFE - Immediately Invoked Function Expression
  (function(yourcode) {

      // The global jQuery object is passed as a parameter
      yourcode(window.jQuery, window, document);

      }(function($, window, document) {

          // The rest of your code goes here!

      }
  ));

要了解有关 IIFE 的更多信息,您可以阅读我的博客文章,标题为“我爱我的 IIFE”

jQuery 就绪事件

许多开发人员将所有代码包装在 jQuery 就绪事件中,如下所示:

   $("document").ready(function() {
      // The DOM is ready!
      // The rest of your code goes here!
  });

或者像这样的较短版本:

   $(function() {
      // The DOM is ready!
      // The rest of your code goes here!
  });

如果您正在执行上述任一模式,那么您应该考虑将不依赖于 DOM 的应用程序部分(例如方法)移到就绪事件处理程序之外。像这样:

   // IIFE - Immediately Invoked Function Expression
  (function(yourcode) {

      // The global jQuery object is passed as a parameter
      yourcode(window.jQuery, window, document);

      }(function($, window, document) {

          // The $ is now locally scoped 
          $(function() {

              // The DOM is ready!

          });

          // The rest of your code goes here!

      }
  ));

这种模式可以更轻松地分离您的逻辑(从代码设计的角度来看),因为并非所有内容都必须包装在单个事件处理程序回调函数中。它还将提高应用程序的页面加载性能,因为并非所有内容都需要立即初始化。一个很好的例子是惰性绑定 DOM 事件处理程序,当 DOM 准备好时不需要绑定。

改编自我的 jQuery 最佳实践博客文章: http: //gregfranko.com/blog/jquery-best-practices/

于 2013-08-19T13:45:38.070 回答
16

您的代码与“建议”方法之间的唯一区别是兼容性和可能更好的压缩。没有速度差异。

作为第一个参数传递window.jQuery给您的 IIFE(立即调用的函数表达式)并$在 IIFE 中命名它只会允许您使用 jQuery 而不会干扰其他将自己分配给 global 的库$。如果您不使用任何其他将自己分配给 global 的库,$那么 IIFE 的第一个参数将没有任何用途。

window将和传递document给您的 IIFE 将允许 JS 压缩器将您的代码转换为类似这样的内容(没有空格),这会给您带来更好的压缩:

(function(a, b, c) {
    a(c).ready(function() {
        // ...
    });
})(window.jQuery, window, document);

除非您广泛使用window,否则document我会这样做:

;(function($) {
    $(function() {
        ...
    });
})(jQuery);
于 2013-08-19T06:07:19.637 回答
5
  1. $(function(){})相当于$('document').ready(function(){});。这取决于您使用哪个,但后者是两者中较旧的一个,并且启动起来更冗长。

  2. 您列出的第二种方法是明确尝试阻止全局变量,并注入已知的全局变量$windowdocument. 建议这样做是为了提高对引入全局变量的容易程度的认识,并对我们注入到页面的代码尽可能“干净”。另外,请注意,如果您遵循显示的评论,则第二种方法不等同于第一种方法。因为 $ 是作为参数插入的,所以此代码与可能希望拥有 $ 符号的其他库兼容。

特别// The rest of the code goes here是在文档准备好之前或触发该事件时可能执行的位置。把它放在传递给 $ 的函数中。

于 2013-08-19T05:53:13.497 回答
3

如果你使用 $ 作为 jQuery 的别名,那么

   $(document).ready(function(){})

  (function($, window, document) {

  // The $ is now locally scoped 

 // Listen for the jQuery ready event on the document
  $(function() {

    // The DOM is ready!

  });

  // The rest of the code goes here!

 }(window.jQuery, window, document));

正如在较早的答案中所指出的,第二种方法使您无法对 jQuery 自由使用 $ 别名,因为它将 jQuery 对象传递给立即调用的函数表达式,这基本上将变量和代码保持在私有状态,并且不会污染全局命名空间。

简而言之,如果你诉诸第一种方法并使用 $ 使用其他库,你会以冲突结束。

于 2013-08-19T06:06:25.483 回答
3

您的链接有答案:

下面的很好,

如果您知道代码将运行的环境。

如果您不关心页面加载性能。

如果您不关心最佳实践。

 $("document").ready(function() {
    // The DOM is ready!
    // The rest of the code goes here
  });

但他们建议,如果您不知道代码运行的环境和

更好的页面加载性能

// IIFE - Immediately Invoked Function Expression
  (function($, window, document) {

    // The $ is now locally scoped 

   // Listen for the jQuery ready event on the document
   $(function() {

     // The DOM is ready!

   });

   // The rest of the code goes here!

  }(window.jQuery, window, document));
  // The global jQuery object is passed as a parameter
于 2013-08-19T05:57:24.217 回答
1

在极少数情况下,您必须使用较旧的 jQuery 版本(如果我没记错的话 - 1.8.X 之前的版本),每当您指定两个 document.ready 块时,IE9 中只会触发第一个块。

现在这是我经历过一次或两次的罕见错误,我无法重现,但我认为这值得一提。

于 2013-08-19T08:32:45.617 回答
0

它被称为self ivokingimmediately invoked函数。这意味着该函数在使用最后一组括号中的参数创建后立即运行。

阅读Javascript 自调用函数立即调用函数表达式 (IIFE)将清楚在哪里使用以及如何使用这些函数

于 2013-08-19T06:18:17.527 回答
0

基于 Jquery 文档:

All three of the following syntaxes are equivalent:

$(document).ready(handler)
$().ready(handler) (this is not recommended)
$(handler)

http://api.jquery.com/ready/

于 2013-08-19T05:53:13.303 回答
0

您可以使用 jquery 使用文档就绪事件,当文档完全加载时发生事件。

 $(function () {
    setTimeout(function () {
        // your code
    }, 0);
})
于 2016-05-06T05:42:03.737 回答