为什么要定义一个匿名函数并将其作为参数传递给jQuery?

Mat*_*rts 94 javascript jquery backbone.js

我正在查看backbone.js截屏视频中的优秀peepcode演示代码.在其中,骨干代码全部包含在传递jQuery对象的匿名函数中:

(function($) {
  // Backbone code in here
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

在我自己的骨干代码中,我只是将我的所有代码都包装在jQuery DOM'ready'事件中:

$(function(){
  // Backbone code in here
});
Run Code Online (Sandbox Code Playgroud)

第一种方法的优点是什么?这样做会创建一个匿名函数,然后立即执行jQuery对象作为函数参数传递,有效地确保$是jQuery对象.这是唯一的一点 - 保证jQuery绑定到'$'还是有其他理由这样做?

Der*_*ley 174

您显示的两个代码块在执行的时间和原因上有很大不同.它们并不是彼此排斥的.他们没有达到同样的目的.

JavaScript模块


(function($) {
  // Backbone code in here
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

这是一个"JavaScript模块"模式,使用立即调用的函数实现.

此代码的目的是为您的代码提供"模块化",隐私和封装.

这个实现是一个由调用(jQuery)括号立即调用的函数.将jQuery传递给括号的目的是为全局变量提供本地范围.这有助于减少查找$变量的开销,并且在某些情况下可以更好地压缩/优化minifiers.

立即调用函数立即执行.一旦功能定义完成,就执行该功能.

jQuery的"DOMReady"功能

这是jQuery的"DOMReady"功能的别名:http://api.jquery.com/ready/


$(function(){
  // Backbone code in here
});
Run Code Online (Sandbox Code Playgroud)

当DOM准备好被JavaScript代码操纵时,jQuery的"DOMReady"函数就会执行.

模板与DOMReady在Backbone Code中

在jQuery的DOMReady函数中定义Backbone代码是不好的形式,并且可能会损害您的应用程序性能.在DOM加载并准备好进行操作之前,不会调用此函数.这意味着你要等到浏览器在定义对象之前至少解析过一次DOM.

在DOMReady函数之外定义Backbone对象是个更好的主意.我和其他许多人一样,更喜欢在JavaScript模块模式中执行此操作,以便为代码提供封装和隐私.我倾向于使用"Revealing Module"模式(参见上面的第一个链接)来访问我模块外部需要的位.

通过在DOMReady函数之外定义对象,并提供一些引用它们的方法,您可以让浏览器在处理JavaScript方面领先一步,从而加快用户体验.它还使代码更加灵活,因为您可以移动东西而不必担心在移动时创建更多DOMREady函数.

即使您在其他地方定义了Backbone对象,您仍可能会使用DOMReady函数.原因是许多Backbone应用程序需要以某种方式操纵DOM.为此,您需要等到DOM准备就绪,因此您需要使用DOMReady函数在定义后启动应用程序.

你可以在网上找到很多这方面的例子,但是这是一个非常基本的实现,同时使用Module和DOMReady函数:



// Define "MyApp" as a revealing module

MyApp = (function(Backbone, $){

  var View = Backbone.View.extend({
    // do stuff here  
  });

  return {
    init: function(){
      var view = new View();
      $("#some-div").html(view.render().el);
    }
  };

})(Backbone, jQuery);



// Run "MyApp" in DOMReady

$(function(){
  MyApp.init();
});
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,带有主干src的"todo"示例应用程序将所有内容都放入dom中. (2认同)
  • 不要忘记javascript模块模式也称为**`IIFE`**. (2认同)

joi*_*egn 14

作为次要的旁注,将$作为参数发送到匿名函数会使$ local本地化,如果$函数被大量调用,则会产生一个小的正性能影响.这是因为javascript首先在本地范围内搜索变量,然后一直遍历到窗口范围($通常存在).


Thi*_*ter 9

它确保即使使用了,也可以始终$在封闭内部$.noConflict()使用.

如果没有这种关闭,你应该使用jQuery而不是一直使用$.