2014-12-02 45 views
0

我本来有这样的代码,下面,在那里我有没有在全局命名空间,我能够调用obj2的功能从OBJ1,反之亦然。一切都很好。JavaScript函数,可以互相访问

(function() { 
    var obj1 = { 
     obj1_f1 : function() { 
     }, 
     obj1_f2 : function() { 
      obj2.obj2_f1(); 
     } 
    }; 
    var obj2 = { 
     obj2_f1 : function() { 
      obj1.obj1_f1(); 
     }, 
     obj2_f2 : function() { 
     } 
    }; 
    $(document).ready(function() { 
     obj1_f1(); 
    }); 
})(); 

但现在我需要从全局范围内调用一个函数在OBJ1对象,所以我就来介绍一个全局对象:

var com_mycompany_make_sure_unique = new function() { 
    // use 'this.' so that obj1 is not in the global namespace 
    this.obj1 = { 
     obj1_f1 : function() { 
     }, 
     obj1_f2 : function() { 
      com_mycompany_make_sure_unique.obj2.obj2_f2(); 
     } 
    }; 
    this.obj2 = { 
     obj2_f1 : function() { 
      com_mycompany_make_sure_unique.obj1.obj1_f1(); 
     }, 
     obj2_f2 : function() { 
     } 
    }; 

    $(document).ready(function() { 
     com_mycompany_make_sure_unique.obj1.obj1_f1(); 
    }); 
}; 

但我不是不太满意与 - 当通过obj1和obj2调用函数时,必须用全局对象名称预先调用所有函数调用。我想我错过了一招。

感谢您的帮助,

保罗

+0

我可能是错的,但如果我理解正确的,这看起来像一个循环引用,最有可能是一个设计错误。 – Dalorzo 2014-12-02 15:49:59

+1

第一个功能不起作用; “准备就绪”的处理程序也许应该叫'obj1.obj1_f1()',因为有一个在所谓的只是'obj1_f1'这一点上没有明显的标志。 – Pointy 2014-12-02 15:50:07

+0

@Pointy:嗯,符号是可见的,但它的价值是'undefined'。 :-) – 2014-12-02 16:00:43

回答

2

你可以做到这一点(见注释):

var com_mycompany_make_sure_unique = function() { 
    // Continue using variables as you were before 
    var obj1 = { 
     obj1_f1 : function() { 
     }, 
     obj1_f2 : function() { 
      obj2.obj2_f2(); 
     } 
    }; 
    var obj2 = { 
     obj2_f1 : function() { 
      obj1.obj1_f1(); 
     }, 
     obj2_f2 : function() { 
     } 
    }; 

    $(document).ready(function() { 
     obj1.obj1_f1(); 
    }); 

    // Return an object that can be used via the `com_mycompany_make_sure_unique` variable 
    return { 
     obj1: obj1, 
     obj2: obj2 
    }; 
}(); 

这有时被称为“显露模块模式”,因为内外部匿名一切作用域功能是私有的,然后你“透露”要通过把它们返回的对象上透露的部分。如果你只需要公开obj1,例如,而不是obj2,你可以这样做:

return { 
    obj1: obj1 
}; 

我的问题,虽然是为什么你需要从全球范围内调用函数?随着现代事件处理和异步模块定义装载机像RequireJS,全球唯一的,你应该真正需要(啊)是AMD功能(S)。


附注:我换成你var ... = new function() { ... };var ... = function() { ... }();有没有必要在这里使用new,并且这样做会倾向于迷惑人(并给出了结果对象一个额外的原型它不需要)。但是你可以使用你原来的形式,如果你喜欢,刚刚结束更改为

this.obj1 = obj1; 
this.obj2 = obj2; 

...而不是返回一个对象。

+1

谢谢。我知道我错过了一招!非常感激。 – user265330 2014-12-02 18:12:45