Improved namespace pattern for Apps Script

Apps Script (simple level) posted on 20th October 2018


If you are a regular reader of these pages, you'll know that I prefer to encapsulate all my code namespaces for all my JavaScript and Apps Script projects. This makes for better organization and avoids global space leakage with all the attendant problems that can cause. There are various namespace patterns to choose from, and I've covered a few of them in some detail elsewhere (search for namespace on this site). 

IIFE

My 'goto' pattern is the IIFE (Immediately Invoked Function Expression), which looks like this in Apps Script.
var Nob = (function (ns) {
  ns.ca='public';
  const cb='private';
  
  // we'll export this function
  ns.fa = function () {
    return ns.ca +':' + cb;
  }
  
  // but not these
  function fb () {
    return ns.fa();
  }
  function fc() {
    return fb();
  }
  
  return ns;
    
})({});

It works by simply creating a new object and assigning things I want to expose as properties of the object, like this.
  Logger.log (Nob.fa());
  Logger.log (Nob.ca);
 
result
    public:private
    public

I'm using the old JavaScript syntax as Apps Script doesn't yet support more modern constructs, but if you are familiar with Node or Es6 you'll also be used to using modules and exports to expose functions to other modules that require them. This IIFE pattern is not a million miles away from that, but it could be improved, and organized better. Note that I have to address functions that are public differently that private ones inside the namespace, and it's not immediately clear what's private and what should be 'exported'. 

So let's clean that up a bit. 
var Bob = (function () {
  const ca='public';
  const cb='private';
  
  // we'll export this function
  function fa () {
    return ca +':' + cb;
  }
  
  // but not these
  function fb () {
    return fa();
  }
  function fc() {
    return fb();
  }
  
  // this is a little like export
  // just expose the things you want public
 
  return {
    fa:fa,
    ca:ca
  }
})();

The improvements are
  • functions get hoisted so there's less reliance on the order of definition
  • it's explicit which functions and variables are targeted for export
  • inside the namespace, all functions are addressed the same way
  • it gets you thinking in modules and exports, ready for when apps script gets updated
If you are using a more modern JavaScript dialect, the same thing can be written like this.
const Cob = ( () => {
  const ca ='public';
  const cb ='private';
  
  // we'll export this function
  const fa = () => `${ca}:${cb}`;
  
  // but not these
  const fb = () => fa();
  const fc = () => fb();
  
  // this is a little like export
  // just expose the things you want public
  return {
    fa,
    ca
  };
})();


For help and more information join our community,  follow the blog,  follow me on twitter, or follow me on g+

You want to learn Google Apps Script?

Learning Apps Script, (and transitioning from VBA) are covered comprehensively in my my book, Going Gas - from VBA to Apps script, All formats are available from O'ReillyAmazon and all good bookshops. You can also read a preview on O'Reilly

If you prefer Video style learning I also have two courses available. also published by O'Reilly.
Google Apps Script for Developers and Google Apps Script for Beginners.

Comments