简体   繁体   English

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

[英]Why define an anonymous function and pass it jQuery as the argument?

I'm looking through the excellent peepcode demo code from the backbone.js screencasts. 我正在看ribs.js截屏视频中出色的peepcode演示代码。 In it, the backbone code is all enclosed in an anonymous function that is passed the jQuery object: 在其中,主干代码全部封装在传递给jQuery对象的匿名函数中:

(function($) {
  // Backbone code in here
})(jQuery);

In my own backbone code, I've just wrapped all my code in the jQuery DOM 'ready' event: 在我自己的主干代码中,我将所有代码包装在jQuery DOM'ready'事件中:

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

What's the point/advantage of the first approach? 第一种方法的目的/优势是什么? Doing it this way creates an anonymous function that is then executed immediately with the jQuery object being passed as the function argument, effectively ensuring that $ is the jQuery object. 这样做会创建一个匿名函数,然后立即将jQuery对象作为函数参数传递来执行该匿名函数,从而有效地确保$是jQuery对象。 Is this the only point - to guarantee that jQuery is bound to '$' or are there other reasons to do this? 这是唯一的观点-保证jQuery绑定到“ $”还是有其他原因呢?

The two blocks of code you have shown are dramatically different in when and why they execute. 您显示的两个代码块在执行时间和执行原因上有很大不同。 They are not exclusive of each other. 它们不是彼此排斥的。 They do not serve the same purpose. 它们的目的不同。

JavaScript Modules JavaScript模块


(function($) {
  // Backbone code in here
})(jQuery);

This is a "JavaScript Module" pattern, implemented with an immediately invoking function. 这是一个“ JavaScript模块”模式,通过立即调用功能实现。

The purpose of this code is to provide "modularity", privacy and encapsulation for your code. 该代码的目的是为您的代码提供“模块化”,保密性和封装性。

The implementation of this is a function that is immediately invoked by the calling (jQuery) parenthesis. 此函数的实现是一个由调用(jQuery)括号立即调用的函数。 The purpose of passing jQuery in to the parenthesis is to provide local scoping to the global variable. 将jQuery传递到括号中的目的是为全局变量提供局部范围。 This helps reduce the amount of overhead of looking up the $ variable, and allows better compression / optimization for minifiers in some cases. 这有助于减少查找$变量的开销,并在某些情况下为压缩器提供更好的压缩/优化。

Immediately invoking functions are executed, well, immediately. 立即调用功能会立即执行。 As soon as the function definition is complete, the function is executed. 功能定义一完成,功能即被执行。

jQuery's "DOMReady" function jQuery的“ DOMReady”功能

This is an alias to jQuery's "DOMReady" function: http://api.jquery.com/ready/ 这是jQuery的“ DOMReady”函数的别名: http : //api.jquery.com/ready/


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

jQuery's "DOMReady" function executes when the DOM is ready to be manipulated by your JavaScript code. 当DOM准备由您的JavaScript代码操作时,将执行jQuery的“ DOMReady”函数。

Modules vs DOMReady In Backbone Code 骨干模块中的模块与DOMReady

It's bad form to define your Backbone code inside of jQuery's DOMReady function, and potentially damaging to your application performance. 在jQuery的DOMReady函数中定义Backbone代码是一种不好的形式,并且可能会损害您的应用程序性能。 This function does not get called until the DOM has loaded and is ready to be manipulated. 在DOM加载并准备好操作之前,不会调用此函数。 That means you're waiting until the browser has parsed the DOM at least once before you are defining your objects. 这意味着您要等到浏览器至少解析一次DOM之后再定义对象。

It's a better idea to define your Backbone objects outside of a DOMReady function. 最好在DOMReady函数之外定义Backbone对象。 I, among many others, prefer to do this inside of a JavaScript Module pattern so that I can provide encapsulation and privacy for my code. 除其他外,我更喜欢在JavaScript模块模式内执行此操作,以便为代码提供封装和隐私。 I tend to use the "Revealing Module" pattern (see the first link above) to provide access to the bits that I need outside of my module. 我倾向于使用“显示模块”模式(请参见上面的第一个链接)来提供对模块外部所需位的访问。

By defining your objects outside of the DOMReady function, and providing some way to reference them, you are allowing the browser to get a head start on processing your JavaScript, potentially speeding up the user experience. 通过在DOMReady函数之外定义对象并提供引用它们的方式,可以使浏览器抢先处理JavaScript,从而有可能加快用户体验。 It also makes the code more flexible as you can move things around without having to worry about creating more DOMREady functions when you do move things. 这也使代码更加灵活,因为您可以随意移动事物,而不必担心在移动事物时创建更多的DOMREady函数。

You're likely going to use a DOMReady function, still, even if you define your Backbone objects somewhere else. 即使您在其他地方定义了Backbone对象,您仍然可能仍将使用DOMReady函数。 The reason is that many Backbone apps need to manipulate the DOM in some manner. 原因是许多Backbone应用程序需要以某种方式操作DOM。 To do this, you need to wait until the DOM is ready, therefore you need to use the DOMReady function to start your application after it has been defined. 为此,您需要等待DOM准备就绪,因此,在定义应用程序之后,需要使用DOMReady函数来启动您的应用程序。

You can find plenty of examples of this around the web, but here's a very basic implementation, using both a Module and the DOMReady function: 您可以在网上找到很多这样的示例,但这是一个非常基本的实现,同时使用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();
});

As a minor sidenote, sending in $ as an argument to an anonymous function makes $ local to that function which has a small positive performance implication if the $ function is called a lot. 作为次要说明,将$作为参数传递给匿名函数会使$在该函数中成为本地函数,如果$函数被调用很多,则对性能的影响很小。 This is because javascript searches the local scope for variables first and then traverses down all the way to the window scope (where $ usually lives). 这是因为javascript首先在本地范围内搜索变量,然后一直向下遍历到窗口范围(通常位于$)。

It ensures you can always use $ inside that closure even if $.noConflict() was used. 它确保即使在使用$.noConflict()下,也始终可以在该闭包内使用$

Without this closure you'd be supposed to use jQuery instead of $ the whole time. 没有这种关闭,您应该一直使用jQuery而不是$

It is to avoid a potential conflict of the $ variable. 这是为了避免$变量的潜在冲突。 If something else defines a variable named $, your plugin may use the wrong definition 如果其他定义了一个名为$的变量,则您的插件可能使用了错误的定义

Refer to http://docs.jquery.com/Plugins/Authoring#Getting_Started for more details 有关更多详细信息,请参见http://docs.jquery.com/Plugins/Authoring#Getting_Started

Use both. 同时使用。

The self invoking function in which you pass in jQuery to prevent library conflicts, and to just make sure jQuery is available as you would expect with $. 自我传递函数,您可以在其中传递jQuery来防止库冲突,并确保jQuery与$一样可用。

And the .ready() shortcut method as required to run javascript only after DOM has loaded: 和.ready()快捷方式方法是仅在DOM已加载后才需要运行JavaScript的方法:

(function($) {
    $(function(){
          //add code here that needs to wait for page to be loaded
    });

    //and rest of code here
})(jQuery);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM