Thoughts on Private in JS

When you get into a bit higher end JavaScript patterns, one thing you’ll read very early on is this concept: that although JavaScript does not have private members or access modifiers, it is possible to achieve this behavior with closures. This is often done through an IIFE and is the simplest implementation of the module pattern. Like so:

[php lang=”JavaScript”]var mod = (function() {
var privateVar = “foo”;
return {
getPrivateVar: function() {
return privateVar;
},
setPrivateVar: function(value) {
privateVar = value;
}
};
}());

console.log(mod.getPrivateVar());
mod.setPrivateVar(“buzz”);
console.log(mod.getPrivateVar());[/php]

The IIFE executes, returning an object with a couple of methods. These methods have access to the original privateVar, which is not accessible anywhere else. Private var, right? All good and well, but I’ve noticed one aspect of this that almost nobody ever talks about…

Modules are singletons.

OK, they are not really singletons in the full sense of the singleton pattern with a static getInstance method and a guard against creating multiple instances. But they are objects that are created a single time and unless you were to copy and paste the code that creates them, there’s no real way to create an additional instance of one of them.

I’m not going off into a “singletons are evil” rant or anything, but it should be pointed out that modules created in this way only have a single instance. This is pretty obvious, since the module is created by an IIFE, which runs once when it is defined, and that’s it. For most things that you would define as “modules” this is probably exactly what you want, which I guess is why nobody talks about it. A module is often a library, like underscore or jquery, etc. Something you generally would not want multiple copies of floating around in the first place.

But say you want some kind of object that it would make sense to have multiple copies of. Say a game with players. If you defined a player object like above, you could only have a single player. So you need to change things somehow to allow for multiple instances.

The first idea is just to remove the IIFE and just have a function that you can call multiple times to create individual objects:

[php lang=”JavaScript”]function playerMaker(pname) {
var name = pname;
return {
getName: function() {
return name;
},
setName: function(value) {
name = value;
}
};
}

var player1 = playerMaker(“Fred”);
console.log(player1.getName());
var player2 = playerMaker(“Barney”);
console.log(player2.getName());[/php]

This works just fine, but do you see the issue here? that return object is created anew every single time you create a new instance. Not a big deal in a trivial example like this, but say you had an object with dozens of properties and methods and you were creating scores of these things. All those methods and properties would be created as brand new methods and properties on every object, cranking up your memory consumption and creation time. Probably not a good idea in most cases.

We could then turn to something like the revealing module pattern, which defines the functions a single time in the module, and then returns an object that references these. In this case, we still want playerMaker to be a function, so we return a function that returns an object that references the single instances of the methods:

[php lang=”JavaScript”]var playerMaker = (function() {
var name = “”;

function getName() {
return name;
}

function setName(value) {
name = value;
}

return function() {
return {
getName: getName,
setName: setName
};
};
}());

var player1 = playerMaker();
player1.setName(“Fred”);
var player2 = playerMaker();
player2.setName(“Barney”);
console.log(player1.getName());
console.log(player2.getName());​[/php]

Only this doesn’t work at all, because the “private” var name is defined only once in the original IIFE and is like a static var amongst all instances. If you tried to move it into the return function at line 12, it wouldn’t work, because then it would not be in the scope that the getName and setName functions would have access to.

The long and the short of it is that for private properties to work, they rely on a closure, and for multiple instances to each have their own accessors and private properties, each one needs to have its own closures. A shared closure can only access a shared property. So we can’t really escape the second example.

Perhaps there is some way to do this, but I suspect that the complexity involved would probably outweigh the benefits.

In my original draft of this post, I went into a minor rant about how you shouldn’t worry about private vars in JavaScript, as it doesn’t have them and it doesn’t make sense to over-engineer all kinds of complexity to simulate them. But I’m not feeling very ranty at the moment, so I deleted all that.

This isn’t to say that the module pattern as commonly used, with its private vars and methods is bad. It’s actually quite simple and elegant as long as you only need a single instance of that module, and I back it up as a great pattern 100%. But if you are trying to extend it to objects with multiple instances, I think you are best to leave privacy behind.

Interestingly, between the time of writing this post and publishing it (a couple of days) I listened to the latest JavaScript Jabber podcast http://javascriptjabber.com/005-jsj-javascript-objects/ on “JavaScript Objects”. A great listen, and some of these very points were brought up. Check that one out. It’s a great new podcast as a whole, and with only 5 episodes so far, well worth going back to the start and checking out all of them.

This entry was posted in JavaScript. Bookmark the permalink.

23 Responses to Thoughts on Private in JS

  1. I was once tasked with getting intellisense to work on libraries that did this kind of thing in Aptana, what a nightmare. I cringe everytime I hear ‘Javascript is as good as any other language, it just needs a good editor’. Unfortunately the language itself is involved there, as are the usages.

    Imo this is solving a problem you don’t have with a problem you don’t want. My gut says people use it because it makes them feel like ninja masters.

    Ahh, I should delete this, but I *am* feeling ranty at the moment – sorry : ).

    • keith says:

      Rant away, that’s why the Internet was created, I think. I’m not particularly trying to solve any problem. I just found it funny that everyone presents the module pattern as a way to achieve private access in JS, but leaves out what seems to be an important aspect of it.

  2. Have you seen JavaScript... On Weed? says:

    function Man() {
    var privates = {};
    privates.derp = 1;
    privates.__proto__ = {
    add: Man.prototype.add.bind(privates),
    subtract: Man.prototype.subtract.bind(privates)
    };
    return privates.__proto__;
    }

    Man.prototype.add = function(n) {
    return (this.derp += n);
    }

    Man.prototype.subtract = function(n) {
    return this.add(-n);
    }

    var man = new Man();
    console.log(man);
    console.log(man.add(1));
    console.log(man.subtract(1));​

    • keith says:

      Not sure if you’re presenting that as a serious solution, but it kind of proves my point about over-engineered solutions.

      • Brandon says:

        Well, it works and I don’t think it’s too complicated. And I think the use of the prototype chain to hide the “private” members is interesting and may be possible to do in a simpler way — I’m just not ninja enough to perfect it. The question remains, however: is it just as bad to use function#bind as is it to create a new function? I understand that bind is effectively creating a new function, but is it any more resource friendly, perhaps optimized in our favorite JS engines, than redefining the function?

  3. Tom Friend says:

    “All those methods and properties would be created as brand new methods and properties on every object, cranking up your memory consumption and creation time.”

    And how is that different than creating multiple instances of an object in any other language? In the case of your game players, each one has to have all of their unique properties stored somewhere. That’s the point of having instances of objects. If I want to keep track of all of Fred’s and Barney’s details, how ever many of those details there are, those details have to occupy their own spaces in memory.

    No?

    • keith says:

      It’s not so much the properties as redefining the same method newly on every single instance.

      • Joel P says:

        I am correct to assume you would advocate leveraging the prototype chain and the “new” keyword to create multiple, similar objects? (Please excuse if I’m asking you to think for me–that’s not my intention.)

        • I’m not going to speak for Keith, but my answer to your question is yes. JavaScript is a prototypal language. You’re writing inefficient code if you create objects with the same interface and functionality if you do not use the prototype object.

        • With prototype inheritance the properties and methods are referenced until overriden at runtime. Generally you don’t do that to methods so they aren’t copied, and with fields they stay the same until changed from default values. That usually doesn’t matter, but say you have a lot of objects with matrix transformations, and most of them are identity, then you can save a lot.

          You do not need to use ‘new’ in the way people usually use it in js inheritance (eg, make copies of the base object). Eg:

          extend = function(subClass, baseClass) {
          function inheritance() {}
          inheritance.prototype = baseClass.prototype;

          subClass.prototype = new inheritance();
          subClass.prototype.constructor = subClass;
          subClass.baseConstructor = baseClass;
          subClass.superClass = baseClass.prototype;
          }

          Of course none of this really matters unless unless you are needing the speed/size it gives, but imo it is cleaner as well (both syntactically and without all the duplication in its runtime structures).

          Channeling flashcoders now : ).

        • keith says:

          Joel, I don’t really want to “advocate” anything. Too many self-proclaimed advocates advocating their heads off out there these days. Personally, I find the simple module pattern as outlined in the first example very useful, and Object.create as discussed in a recent post to be a really clean way of creating multiple instances of an object. But lots of people find using new with constructor functions useful and easy to think with, and plenty of libraries out there use it.

    • Brandon says:

      In other languages (I’m particularly thinking of compiled C++ code), instances of the class share one copy of the method, but the caller passes a “this” pointer as the first argument

  4. felix says:

    I agree it’s strange that nobody mentions that the Revealing Module Pattern and similar are single instance patterns.

    I typically use RMP for singleton style grouping of logic, and prototype style ‘classes’ for multiple instances of an object. It’s a shame there is not a single JS pattern that handles both cases.

    I know classes are not cool at the moment and we are all suposed to adapt our brains to JSs lack of structure, but my personal feeling is that java style OO classes have served us well for a long time and ‘if it ain’t broke don’t fix it’. I imagine in the future, more structured languages that compile to JS will become more popular (e.g. Google’s Dart).

  5. Erik says:

    Closure-enforced encapsulation is great in theory (and as you said, in some situations in practice as well), but for most straightforward production JavaScript code, I’m a big fan of just using the leading underscore as an indicator of “privateness”. I trust myself and my colleagues not to compromise a design by reaching around privacy-by-convention, so the code I end up with is just as maintainable as code with “true” private members but without a lot the complexity of trying to add a language feature that isn’t really there.

    ActionScript 3 was a pretty nice language…

  6. This may be too convoluted — what do you think? — but it works. I’m somewhat new to JS. What are the (plusses and) minuses of the following?

    [If the following loses its whitespaces, it’s going to look a lot more complicated than it is.]

    function AlienConstructorFactory() {
    return function() {
    var _hitPoints = 3, _alive = true;

    return {
    sustainDamage : function() {
    _hitPoints -= 1;
    if ( _hitPoints < 1 ) _alive = false;
    },
    isAlive : function() {
    return _alive;
    }
    };
    };
    }

    var BeeperConstructor = AlienConstructorFactory();
    var beeper = BeeperConstructor();

    var BooperConstructor = AlienConstructorFactory();
    var booper = BooperConstructor();

    booper.sustainDamage();
    booper.sustainDamage();
    booper.sustainDamage();

    beeper.sustainDamage();

    document.getElementById( "output" ).innerHTML = booper.isAlive() + " " + beeper.isAlive();

    alert( beeper._isAlive ); //undefined

    • Keith Peters says:

      Marcus, this is essentially my second example. The “minus” of this is that every time you call your constructor function, a new object is created, and in that object a new sustainDamage function is created and a new isAlive function is created. If you created 100 of those objects, JavaScript would be recreating those functions 100 times, each one taking time to create, and using up memory. Ideally in object creation, if instances are all going to have the same functions, you would find some way to share them. In JavaScript, you would put those functions in the prototype of the instances. In that case, you could create a million instances but those functions would only be created a single time, on the prototype.

      Is this an actual problem in a real world application? It completely depends on the application, the size of the object, how many methods it has, how big they are, how many instances you are going to create.

      • Yeah. I see your point.

        It’s not for a real project. It’s just code I made up after reading your post, seeing if I could come up with a solution. I think I’ve now convinced myself, with your help, that there isn’t one — not if you insist on having private “members” that are also not repeated in each instance.

  7. Dave Stewart says:

    The day I stopped worrying about properties being private in JS was the day I ended up with less brain-pain and a lot more work done.

    Douglas Crockford and all sorts of other people have also given up on making JS do things it’s not really supposed to do.

    I’m with Erik and the underscore method, but I usually don’t even bother doing that as I have a well defined API. As you say, direct access executes quicker, and if you really need something private, make it private, but I find it pays not to think like AS3 in JS1.x

    Wouldn’t it be nice if AS3 was available in the browser… 🙂

  8. Paul Grenier says:

    I wrote a series of articles some time ago about privacy, objects, and classes: http://www.codedodger.com/?s=5+guys.

    Since then, I’ve grown far more accustomed to “naked” composite objects–where the only thing I care about is delegation instead of privacy and delegation. While privacy is nice, performance and “debugability” is better.

    However, if you find yourself needing to protect or obfuscate object state, take a look at my articles which show an evolution from IFFE to constructor and even prototype methods with access to the private internals.

  9. While returning methods solves problem you point out, and acts in similar way as interface for class, i don’t like that solution where my code is in return statement, it creates very unreadable and hard to follow code.

  10. Alan Shaw says:

    “ActionScript 3 was a pretty nice language…”

    I’m currently working with a rather large Flex codebase which has lots of Fortranisms (eg bunch of parallel arrays of properties instead of one array of objects; like pre-struct C style) and altogether too much JavaScriptitude (eg deeply indented anonymous functions defined right where they’re being passed as callbacks, when they would be much more readable as named functions defined just outside the point of use), all of which I regard as brush to be cleared as I go along, and I have ‘fixed’ several hard-to-find ‘bugs’ simply as a ‘side effect’ of clarifying the code.

    So I’m not the type to rely on convention over protection (gimme a condom every time), and I’ve gotten even more anal (gimme a condom every time) about keeping even the owner of a private variable from being able to modify it directly if there is a derived property that depends upon it.

    This has led me to use an IIFE in an AS3 class like so:

    private var wealthScope:Object = (function():Object {
    var _wealth:Number;
    return {
    getWealth: function():Number {
    return _wealth;
    },
    setWealth: function(value:Number):void {
    _wealth = value;
    rank = Ranks.getPlayerRank(_wealth);
    }
    };
    }());

    protected function setWealth(value: Number): void
    {
    wealthScope.setWealth(value);
    }
    public function get wealth(): Number
    {
    return wealthScope.getWealth();
    }

    (Cuddled curlies is the signal that here be JS)

    ‘Readability of code’ is a function of, among other things, ‘what year is this, and what idioms can you reasonably expect a non-ninja programmer to understand’.

  11. dotnetCarpenter says:

    Hi Keith. I just wanted to comment on “a guard against creating multiple instances”. You actually can do that very simply. Just do:
    var mod = new function() {
    var privateVar = “foo”;
    return {
    getPrivateVar: function() {
    return privateVar;
    },
    setPrivateVar: function(value) {
    privateVar = value;
    }
    }
    }
    console.log(mod.getPrivateVar())
    var instance = new mod()//<- will fail

    I did a whole bunch of experiments a while ago: http://jsfiddle.net/dotnetCarpenter/9dbhT/

Leave a Reply