Javascript 为什么定义一个匿名函数并将其作为参数传递给 jQuery?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10371539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why define an anonymous function and pass it jQuery as the argument?
提问by Matt Roberts
I'm looking through the excellent peepcode demo code from the backbone.js screencasts. In it, the backbone code is all enclosed in an anonymous function that is passed the jQuery object:
我正在浏览来自主干.js 截屏视频的优秀 peepcode 演示代码。在其中,主干代码全部包含在传递 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. Is this the only point - to guarantee that jQuery is bound to '$' or are there other reasons to do this?
第一种方法的要点/优势是什么?这样做会创建一个匿名函数,然后立即执行,将 jQuery 对象作为函数参数传递,有效地确保 $ 是 jQuery 对象。这是唯一的一点 - 保证 jQuery 绑定到 '$' 还是有其他原因这样做?
回答by Derick Bailey
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 模块”模式,通过立即调用函数实现。
- http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript
- http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
- http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript
- http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
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. The purpose of passing jQuery in to the parenthesis is to provide local scoping to the global variable. This helps reduce the amount of overhead of looking up the $
variable, and allows better compression / optimization for minifiers in some cases.
this 的实现是一个由调用方(jQuery)
括号立即调用的函数。将 jQuery 传入括号的目的是为全局变量提供局部作用域。这有助于减少查找$
变量的开销,并在某些情况下允许对缩小器进行更好的压缩/优化。
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. This function does not get called until the DOM has loaded and is ready to be manipulated. That means you're waiting until the browser has parsed the DOM at least once before you are defining your objects.
在 jQuery 的 DOMReady 函数内定义 Backbone 代码是一种糟糕的形式,并且可能会损害您的应用程序性能。在 DOM 加载并准备好进行操作之前,不会调用此函数。这意味着在定义对象之前,您需要等待浏览器至少解析一次 DOM。
It's a better idea to define your Backbone objects outside of a DOMReady function. 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. 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.
在 DOMReady 函数之外定义 Backbone 对象是一个更好的主意。我和其他许多人一样,更喜欢在 JavaScript 模块模式中执行此操作,以便为我的代码提供封装和隐私。我倾向于使用“揭示模块”模式(请参阅上面的第一个链接)来提供对模块之外我需要的位的访问。
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. 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 函数之外定义您的对象,并提供一些引用它们的方法,您可以让浏览器在处理您的 JavaScript 时抢占先机,从而可能加快用户体验。它还使代码更加灵活,因为您可以移动事物而不必担心在移动事物时创建更多 DOMREady 函数。
You're likely going to use a DOMReady function, still, even if you define your Backbone objects somewhere else. The reason is that many Backbone apps need to manipulate the DOM in some manner. 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.
您仍然可能会使用 DOMReady 函数,即使您在其他地方定义了 Backbone 对象。原因是许多 Backbone 应用程序需要以某种方式操作 DOM。为此,您需要等到 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:
你可以在网上找到很多这样的例子,但这里有一个非常基本的实现,使用模块和 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();
});
回答by joidegn
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 首先在局部范围内搜索变量,然后一直向下遍历到窗口范围( $ 通常所在的位置)。
回答by ThiefMaster
It ensures you can alwaysuse $
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
而不是一直使用$
。
回答by Andrew Brock
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_Startedfor more details
有关更多详细信息,请参阅http://docs.jquery.com/Plugins/Authoring#Getting_Started
回答by Andrew
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);