Recommend way of scoping private members in javascript module

Conside the following JavaScript code. The function definitions all seem to achieve the same thing. Is there any recommended convention for defining the functions which are then 'revealed' in the return dictionary object?

var testModule = (function(){
      var counter = 0;

      var localFunc1 = function() {
        return "local 1";
      }

      function localFunc2() {
        return "local 2";
      }

      this.localFunc3 = function() {
        return "local 3";
      }

      localFunc4 = function() {
        return "local 4";
      }

      return {      
        proxy1: localFunc1,
        proxy2: localFunc2,
        proxy3: localFunc3,
        proxy4: localFunc4
      };
    })();

Answers


I don't think that there is any real preferred method. The most common setup I've seen involves creating all of your methods as local (using var) then returning an object that exposes the public methods.

A couple of things to note:

  • this.localFunc3 will only work if your object is instantiated with the 'new' keyword
  • when returning your object, remove the () from each function so that you are returning a reference to the function and not the function's returned value
  • localFunc4 will be global since it has no 'var' keyword in front of it

When working with a module pattern like this, I tend to go for something along the lines of:

var Obj = ( function () {
    var private_static = 'this value is static';
    return function () {
        //-- create return object
        var _self = {};
        //-- create private variables
        var private_variable = 'this value is private';
        var func1 = function () {
            return 'value 1';
        };
        //-- attach public methods
        _self.func1 = func1;
        //-- return the object
        return _self;
    };
} )();

Some notes about this method:

  • allows for private static variables (if you don't need private static variables, you can remove the closure)
  • by creating the _self reference first, you can pass a self reference to any objects instantiated from within that need a reference to their parent
  • I like that I can reference all internal functions without _self.whatever or this.whatever, ignoring whether or not they are private or public

The definitions do not achieve the exact same thing.

  • var localFunc1 and function localFunc2 do the same thing, they create functions only available inside your outer function.

  • this.localFunc3 and localFunc4 are not really local functions: they both belong to the window object (this in that context is window, and localFunc4 is declared without the var statement).

So, the latter two don't even need to be exposed on your returned object, since they're already global. And, actually, you are not exposing any functions on your return object, you are exposing their return values, since you invoke each of them. Were you trying to do this?

return {      
   proxy1: localFunc1,
   proxy2: localFunc2,
   proxy3: localFunc3,
   proxy4: localFunc4
};

Note: I recommend you watch this video where Douglas Crockford explains the multiple ways to deal with inheritance in JavaScript. I believe you are looking for what he calls "parasitic inheritance".


Need Your Help

Facebook invite friends doesn't work on native android browser

javascript facebook mobile

I am developing facebook mobile web app, I tested invite friends on all desktop browsers and it works fine, it is also works fine on firefox for mobile. But it is not working on android native brow...

Can I create a unique filename based on ProcessID and ThreadID?

multithreading delphi cgi isapi

I have a delphi (Win32) web application that can run either as a CGI app, ISAPI or Apache DLL. I want to be able to generate a unique filename prefix (unique for all current requests at a given mom...