james
james

Reputation: 31

javascript module pattern supporting mutual dependency

It seems that using the following javascript module pattern, it is not possible to have mutually dependent modules:

var AA = (function(module, BB){
  module.sayHello = function(){
    alert("AA: hello!");
  };
  module.pokeYourFriend = function(){
    BB.sayHello();
  };
  return module;
})(AA || {}, BB);

var BB = (function(module, AA){
  module.sayHello = function(){
    alert("BB: hello!");
  };
  module.pokeYourFriend = function(){
    AA.sayHello();
  };
  return module;
})(BB || {}, AA);


> AA.pokeYourFriend();
*TypeError: Cannot call method 'sayHello' of undefined*

the above fails because BB does not exist at the time AA is created.

is there a pattern that allows this, or should mutual dependency be forbidden?

Upvotes: 3

Views: 380

Answers (1)

Vivin Paliath
Vivin Paliath

Reputation: 95508

The RHS values of AA and BB are function expressions, which are evaluated in top-down order (which is the normal order in Javascript). Therefore, you cannot use BB before BB has been defined.

Instead of self-invoking, you can use a "constructor" that creates these modules and assigns a name to them ("AA", or "BB"):

var create = (function(name) {
   var _friend = null;
   var _name = name;

   return {
      sayHello: function() {
         alert(_name + ": hello!");
      },
      pokeYourFriend: function() {
         if(_friend != null) {
            _friend.sayHello();
         }
      },
      setFriend: function(friend) {
         _friend = friend;
      }
   };
});

var AA = create("AA");
var BB = create("BB");

AA.setFriend(BB);
BB.setFriend(AA);

AA.pokeYourFriend(); //alerts "BB: hello!"
BB.pokeYourFriend(); //alerts "AA: hello!"

Upvotes: 2

Related Questions