我正在查看backbone.js截屏视频中优秀的peepcode演示代码。在其中,主干代码全部包含在传递jQuery对象的匿名函数中:
(function($) {
// Backbone code in here
})(jQuery);
在我自己的骨干代码中,我只是将我的所有代码都包装在jQuery DOM'ready'事件中:
$(function(){
// Backbone code in here
});
第一种方法的优点是什么?这样做会创建一个匿名函数,然后立即执行jQuery对象作为函数参数传递,有效地确保$是jQuery对象。这是唯一的一点 - 保证jQuery绑定到'$'还是有其他理由这样做?
答案 0 :(得分:170)
您显示的两个代码块在执行的时间和原因上有很大差异。它们并不是彼此排斥的。他们没有达到同样的目的。
(function($) {
// Backbone code in here
})(jQuery);
这是一个“JavaScript模块”模式,使用立即调用函数实现。
此代码的目的是为您的代码提供“模块化”,隐私和封装。
这是一个由调用(jQuery)
括号立即调用的函数。将jQuery传递给括号的目的是为全局变量提供本地范围。这有助于减少查找$
变量的开销,并允许在某些情况下更好地压缩/优化minifiers。
立即执行立即调用函数。一旦功能定义完成,就执行该功能。
这是jQuery的“DOMReady”函数的别名:http://api.jquery.com/ready/
$(function(){
// Backbone code in here
});
jQuery的“DOMReady”函数在DOM准备好被JavaScript代码操作时执行。
在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();
});
答案 1 :(得分:14)
作为次要的旁注,将$作为参数发送到匿名函数会使该函数的$ local,如果$函数被大量调用,则会产生小的正性能影响。这是因为javascript首先在本地范围内搜索变量,然后一直遍历到窗口范围($通常存在)。
答案 2 :(得分:9)
即使使用了$.noConflict()
,它也可以确保您始终在该关闭中使用$
。
如果没有这种关闭,你应该一直使用jQuery
而不是$
。
答案 3 :(得分:4)
这是为了避免$ variable的潜在冲突。 如果其他东西定义了一个名为$的变量,那么你的插件可能会使用错误的定义
有关详细信息,请参阅http://docs.jquery.com/Plugins/Authoring#Getting_Started
答案 4 :(得分:0)
同时使用。
自调用函数,在其中传入jQuery以防止库冲突,并确保jQuery可用,就像您期望的那样使用$。
只有在加载DOM后才能运行javascript所需的.ready()快捷方法:
(function($) {
$(function(){
//add code here that needs to wait for page to be loaded
});
//and rest of code here
})(jQuery);