Christian Heilmann

Again with the Module Pattern – reveal something to the world

Wednesday, August 22nd, 2007 at 2:12 am

Not too long ago I was raving about the beauty of the Module Pattern in JavaScript and the annoyance I felt with it when it comes to repetition of long namespaces when calling or reading public methods and properties from other public methods and properties.

To recap, the “classic” Module Pattern means you define a variable as an anonymous function that gets immediately called with (). You define private functions and variables and return your public variables and functions as properties and methods of an anonymous object:

var classicModulePattern = function(){
  var privateVar = 1;
  function privateFunction(){
    alert('private');
  }
  return {
    publicVar:2,
    publicFunction:function(){
      classicModulePattern.anotherPublicFunction();   
    },
    anotherPublicFunction:function(){
      privateFunction();
    }
  }
}();
classicModulePattern.publicFunction();

The beef I had with that is that you need to repeat the name of the main object when you want to call one public method from another or access public variables. The other bit I was annoyed about is having to switch to object literal notation for the things you want to make public.

Inspired by the comments on the blog post on the YUI about the module pattern and pubstandards, I started advocating using a named object called pub to append methods and properties to before returning it. That way you can call public methods via the pub.methodName shortcut notation instead of repeating the main name:

var namedObjectModulePattern = function(){
  var pub = {};
  var privateVar = 1;
  function privateFunction(){
    alert('private');
  };
  pub.publicVar = 2;
  pub.publicFunction = function(){
  pub.anotherPublicFunction();    
  };
  pub.anotherPublicFunction = function(){
    privateFunction();
  };
  return pub;
}();
namedObjectModulePattern.publicFunction();

During a Q&A session in a training in Hongkong yesterday I showed this to Douglas Crockford and asked him what he thinks of it. He didn’t mind the idea, but considered even the pub object redundant.

There is another option which I am hereby calling the Revealing Module Pattern. In this permutation you simply define all your functions and variables in the private scope and return an anonymous object at the end of the module with pointers to the private variables and functions you want to reveal as public:

var revealingModulePattern = function(){
  var privateVar = 1;
  function privateFunction(){
    alert('private');
  };
  var publicVar = 2;
  function publicFunction(){
    anotherPublicFunction();    
  };
  function anotherPublicFunction(){
    privateFunction();
  };
  // reveal all things private by assigning public pointers
  return {
    publicFunction:publicFunction,
    publicVar:publicVar,
    anotherPublicFunction:anotherPublicFunction
  }
}();
revealingModulePattern.publicFunction();

This keeps the syntax of the whole script consistent and makes it obvious at the end which of the functions and variables can be accessed publicly. The other benefit is that you can reveal private functions with other, more specific names if you wanted to.

var revealingModulePattern = function(){
  var privateVar = 1;
  function privateFunction(){
    alert('private');
  };
  var publicVar = 2;
  function publicFunction(){
    anotherPublicFunction();    
  };
  function anotherPublicFunction(){
    privateFunction();
  };
  // reveal all things private by assigning public pointers
  return {
    init:publicFunction,
    count:publicVar,
    increase:anotherPublicFunction
  }
}();
revealingModulePattern.init();

You can even return values as the public properties by calling the functions in the anonymous object:

var revealingModulePattern = function(){
  var privateVar = 1;
  function privateFunction(){
    alert('private');
  };
  var publicVar = 2;
  function publicFunction(){
    anotherPublicFunction();    
  };
  function anotherPublicFunction(){
    privateFunction();
  };
  function getCurrentState(){
    return 2;
  };
  // reveal all things private by assigning public pointers
  return {
    init:publicFunction,
    count:publicVar,
    increase:anotherPublicFunction,
    current:getCurrentState()
  }
}();
alert(revealingModulePattern.current) 
// => 2
revealingModulePattern.init();

Of course the example names here are far from what I would use in a real script, but it shows the power of this pattern.

Share on Mastodon (needs instance)

Share on Twitter

Newsletter

Check out the Dev Digest Newsletter I write every week for WeAreDevelopers. Latest issues:

Dev Digest 146: 🥱 React fatigue 📊 Query anything with SQL 🧠 AI News

Why it may not be needed to learn React, why Deepfake masks will be a big problem and your spirit animal in body fat! 

Dev Digest 147: Free Copilot! Panel: AI and devs! RTO is bad! Pi plays!

Free Copilot! Experts discuss what AI means for devs. Don't trust containers. Mandated RTO means brain drain. And Pi plays Pokemon!

Dev Digest 148: Behind the scenes of Dev Digest & end of the year reports.

In 50 editions of Dev Digest we gave you 2081 resources. Join us in looking back and learn about all the trends this year.

Dev Digest 149: Wordpress break, VW tracking leak, ChatGPT vs Google.

Slowly starting 2025 we look at ChatGPT vs Google, Copilot vs. Cursor and the state of AI crawlers to replace web search…

Dev Digest 150: Shifting manually to AI.

Manual coding is becoming less of a skill. How can we ensure the quality of generated code? Also, unpacking an APK can get you an AI model.

My other work: