2014-12-02 67 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