通常,ready
事件 jQuery 函数是这样调用的
$(function() { /* ... */ });
// or
jQuery(function() { /* ... */ });
// or
jQuery(document).ready(function() { /* ... */ });
最重要的是,该函数没有给出特定的上下文;jQuery 为函数提供的实际上下文是HTMLDocument
元素,与参数无关(在最后一个示例中,document
)。为什么会这样是另一个话题。
通常,这些函数中的每一个都会在加载完所有内容之后调用,但不一定。在您的情况下,在事件发生MyNameSpace
之前有一个参考。ready
即使 Javascript 是一种LALR类型的语言,并且它会找到稍后声明的符号,这也不是一个好习惯。如果MyNameSpace
稍后在 jQuery 触发ready
回调函数之前设置为其他内容怎么办?您的ready
回调不会得到那个新的参考。除非有意,否则应该在回调内部ready
进行引用,当一切都准备好时。
然后,在ready
回调内部,还有其他技术可以将上下文分配给函数。lonesomeday几乎给出了正确的方法来完成你想做的事情。
(function() {
// this == MyNamespace
}).call(MyNamespace);
上面的代码立即执行了一个匿名函数,其中this == MyNameSpace
注意:此处描述了apply和call之间的区别
现在,是您提供的代码的底部:
//load the additional files that are needed and fire onReadyCallback
MyNameSpace.Util.loadFiles(defaultJsFiles,function(){
MyNameSpace.Util.require(['My.App','My.Theme','My.DomHandler'], function(){
onReadyCallback.apply(window);
});
});
这是有问题的,也是不必要的。该函数是否onReadyCallback
只需要在那里,还是会被多次调用?如果只需要调用一次,请保留全局命名空间,只需执行以下操作:
//load the additional files that are needed and fire onReadyCallback
MyNameSpace.Util.loadFiles(defaultJsFiles,function(){
MyNameSpace.Util.require(['My.App','My.Theme','My.DomHandler'], function(){
// if everything is done loading, the function will be executed, otherwise
// it's execution will be postponed later
jQuery(function() {
// create our nicely wrapped anonymous function now
(function() {
if(!this.loggedIn()){
return;
}
// ...Lots of Code referring to MyNameSpace using "this"
})(MyNameSpace); // grab our most recent reference of `MyNameSpace`
});
});
});
如果您不喜欢缩进(这只是开发人员的口味),请将ready
回调中的所有内容替换为(类似):
initMyNameSpace.apply(MyNameSpace);
并在全局空间之外创建您的函数:
function initMyNameSpace() {
if(!this.loggedIn()){
return;
}
// ...Lots of Code referring to MyNameSpace using "this"
};
但我建议,至少,把它放在require
回调函数中,这样它......
- ...不会使用一次性运行函数污染全局命名空间
- ...无法从任何地方访问(保密)
- ...在编辑源代码时可以快速找到
- 等等
注意:通常,apply和call用于避免重复访问对象,例如some.thing.pretty.deep = value;
或者当一个函数需要应用于许多但不是所有对象时,因此扩展对象的原型并不是一个好主意。
无论如何,这是我的意见,以及我将如何做事,而无需更多地了解您的代码或您在做什么。