使用apply方法调用jQuery document.ready处理程序?

时间:2011-06-08 16:26:04

标签: javascript jquery anonymous-function document-ready

以下是我在具有一些复杂依赖项的项目中使用的代码。在确保已加载所有依赖项之后,我还会触发下面给出的 onReadyCallback()。我有两个问题:

  1. 使用anonymousHandler.apply(MyNameSpace)是否正确,为Document.ready
  2. 调用匿名处理函数的apply方法
  3. 据我所知,因为我使用的是apply方法,所以无论文档的就绪状态如何,匿名函数都会立即触发。那么我怎样才能将 MyNameSpace 的上下文传递给 anonymousHandler ,以便函数内的“this”引用MyNameSpace

    var onReadyCallback = function(){
        jQuery(document).ready(function(){
           if(!this.loggedIn()){
              return;
           }
           ...Lots of Code referring to MyNameSpace using "this"
    
        }.apply(MyNameSpace));
    };
    
    //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);          
        });
    });
    

2 个答案:

答案 0 :(得分:4)

如何使用匿名函数和call

jQuery(document).ready(function() {
    (function() {
        // this == MyNamespace
    }).call(MyNamespace);
});

答案 1 :(得分:1)

通常,ready事件jQuery函数就像这样调用

$(function() { /* ... */ });
// or 
jQuery(function() { /* ... */ });
// or
jQuery(document).ready(function() { /* ... */ });

底线,该功能没有给出特定的上下文; jQuery给函数提供的实际上下文是HTMLDocument元素,不管参数如何(在最后一个例子中,document)。为什么这是另一个主题。

通常,在加载所有内容后,稍后会调用这些函数中的每一个,但不一定。在您的情况下,MyNameSpace事件发生之前会引用ready。即使Javascript是LALR类型的语言,并且它会找到稍后声明的符号,这也不是一个好习惯。如果在jQuery触发MyNameSpace回调函数之前将ready设置为其他内容,该怎么办?您的ready回调不会获得新的引用。除非是有意的,否则当所有内容都准备就绪时,应该在{{1>}回调内

然后,在ready回调中,还有其他技术可以为函数分配上下文。 lonesomeday几乎已经给出了正确的方法来完成你想要做的事情。

ready

上面的代码立即执行匿名函数,其中(function() { // this == MyNamespace }).call(MyNamespace);

注意应用调用之间的区别被描述为here

现在,您提供的代码的底部是:

this == MyNameSpace

这是有问题的,也是不必要的。函数//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" }; 回调函数中,以便...

  1. ...不会使用一次运行功能污染全局命名空间
  2. ...无法从任何地方访问(保持私密状态)
  3. 编辑源代码时可以快速找到
  4. ...
  5. 注意:通常,应用调用用于避免重复访问require之类的对象或者当一个功能需要时应用于许多但不是所有对象,因此扩展对象的原型并不是一个好主意。

    无论如何,这是我的意见,以及如何在不了解您的代码或您正在做什么的情况下做事情。