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 more like this see Google Apps Scripts Snippets

For help and more information join our community, follow the blog or follow me on Twitter