JavaScript: Private Variables are Evil

April 6th, 2010 by Mike Wilcox

One of the more exciting discoveries in JavaScript programming was in 2001 when Douglas Crockford found the ability to create private variables in JavaScript. Granted, this was exciting, and as with any new toy, everybody started using them. Since then, you can’t find a book, tutorial or blog that doesn’t have some kind of “How to!!” showing how to do it. But, despite the excitement, private variables should be used in moderation at best.

So why are they evil? The title of this post is a tongue in cheek homage to Mr Crockford who not only discovered private variables, but coined the term eval is evil. However, his statement refers to potential security leaks if you use eval carelessly. Private variables will not cause security leaks but what they will almost undoubtedly do is help you code yourself in a corner.

Privacy Primer

In a nutshell, here’s how private variables work with the following example. The new Widget is created and with it, 20 is passed in as the width argument. The width argument can only be seen within the immediate Widget constructor — or that function’s scope. Since the method getWidth is also within that functional scope, it can see width. Everything outside of it cannot, hence w.width is undefined.

Example #1a – Instance Privacy

var Widget = function(width){
    this.borderWidth = 1;
    this.getWidth = function(){
        return width + this.borderWidth*2;
    }
};
var w = new Widget(20);
w.width === undefined
w.getWidth() === 22;

The example already starts to illustrate the point. It’s apparent why a psuedo-getter, the getWidth function may be desirable, since when you get that property you want it to include the border widths as well. But what if you want to know the width without the borders? It can be done with subtraction, but only because this.borderWidth is public. Of course, borderWidth could be private, and then a getter could be used for that. And in addition to the borderWidth and width getters, you may as well make a realWidth getter as a convenience function… now you’re all set, right?

No, not yet. What if you need to set these properties? Now setters are needed too. After adding those, what’s left? I’ll tell you what’s left — a mess:

Example #1b – Instance Privacy

var Widget = function(){
    var borderWidth;
    var width;
    this.getWidth = function(){
        return width + borderWidth*2;
    }
    this.setWidth = function(w){
        width = w;
    }
    this.getBorderWidth = function(){
        return borderWidth;
    }
    this.setBorderWidth = function(b){
        borderWidth = b;
    }
    this.getRealWidth = function(){
        return width;
    }
// no setter for realWidth
};

The example is not arbitrary. The overall question is: what is the purpose for using a private variable? Private vars are quite important in enterprise code, if say, you are one of one thousand programmers working on an operating system. That’s an exaggerated but relevant example. In order for privacy to be useful, you need to be really talking about multitudes of programmers, all of different abilities, all working with the code that you provide to them that carefully highlights which properties and methods they can and can’t access. You also have hundreds of modules and components that all have to work together, so architectural integrity of the API is paramount or else things will either not work or be perpetually changing.

In AJAX applications are not something that is the scale of an operating system. Most of the time it’s one person writing the code, and the flip side is that you have teams of maybe thirty people (approximately the size of the largest I’ve been on anyway). So you’re basically protecting yourself from yourself, or maybe your protecting your co-worker. Or is it just screwing them?

Let’s look at one of the more popular patterns being used in AJAX today, which is a wrapped anonymous function that hides the variables from the global space yet keeps them accessible to the code:

Example #2 – Multiple Privacy

(function(){
    var _idx;
    var getUniqueId = function(){
        return _idx++;
    };
    window.library = {
        Widget: function(){
            this.id = getUniqueId();
        }
    };
})();

This pattern is used for several reasons: it keeps the library namespace clean of temporary variables and methods and/or keeping the global space clean. This pattern is different than the first. in the first, the private variables are only accessible within each instance; here multiple items have access to the privates.

But now what if the next widget is the tenth one and it should do something different? Or what if getUniqueId() is needed somewhere else in the code? Well, since it’s your personal code (or you are on a small team) you simply change it to make it accessible. But then… why make it private in the first place?

Example #3 – Protected Variables

(function(){
    var mm = library.namespace.methods.myMethod;
    app = {
        calculate: function(){
            return mm(this.var, this.otherVar, this.moreVar)
        }
    };
})();

This pattern arguably has more legitimacy than the others. An otherwise verbose method and namespace is aliased into something very short. If you notice you could alternatively make this alias a property of app, and then calculate could use this.mm instead — and then we wouldn’t need the private variable. If the plan is to use mm() many times, you would actually save a few bytes, not to mention not having to type “this-dot” which is a bit more finger-friendly. Finally, I can’t argue that the mm() method is not accessible because you could actually access the original myMethod(). So is this privacy pattern acceptable? Nope. You can even run into problems with this one.

This position is not one of speculation – here is a real world example. The original code for the FileUploader in the Dojo Toolkit was written using the Multiple Privacy pattern. These hidden variables and methods were used to create the upload button. At the time this looked to be not only very clean code, but legitimate. There were also semantics involved – that button creation really had little to do with FileUpload’s “public” methods, where the developer controls file selections and uploads. After the button was created that private stuff was unusable; they couldn’t create another button, so the code was done and served its purpose. However, the FileUploader is a widget, and a Dojo rule is that all widgets can be extended, meaning you should be able do something like this:

var CustomFileUploader =  dojo.extend(dojox.FileUploader, {
    ...custom stuff here...
});

Note: It is not accurate code; some liberties were used to make it more readable for non-Dojo’ers.

CustomFileUploader was created in a new scope – a scope that could not see all of my private variables and functions. It didn’t work. FileUploader could not be extended. The newer version of the FileUploader has been re-written without using this pattern.

There were and still are problems in Dojo with the protected variable pattern for the same reason. These widgets can’t be extended. There’s been a discussion on the Dojo list and everybody has agreed these patterns should be factored out and no longer used.

I know what you’re thinking. But Mike, I’m not a library committer, I write my own code for my own websites. So I won’t run into trouble. I’m afraid you’d be “thinking wrong”.

In the previous version of Club AJAX, all of the UI code was written in pretty much one big anonymous function, leaving only access to a couple of initialization functions (for posterity’s sake, the code is available here). Several months after it was written a bug was discovered in it. The code was fairly complicated and not easy to trace. The plan was to use the Firebug DOM tab and browse through the objects and methods and then overwrite some code using the Firebug command line to pinpoint the issue.

Wrong! Practically all of the code was hidden – protecting myself from myself. I had to find the bug the hard way – reading and re-understanding the code, logging out information, and changing things using trial and error. It’s not that it took an incredibly long time to fix, but it was a lesson well-learned. All that private stuff served no purpose except to make my own code harder to debug.

Conclusion

The reduction of privacy patterns is the right move in writing more maintainable code. Leave object properties as properties, and don’t obfuscate them with privacy patterns out of laziness or cleverness. This is not to say that local variables are bad. Using this.i in a for-loop would be absolute madness.

And they do have there uses. One of the benefits of Instance Privacy pattern is it’s a great “Hello World” to introduce beginners into advanced JavaScript. It makes it clear how scope works and is often their “ah ha” moment.

It’s also possible that you may be writing code for a client that is using your code, and you do literally want to protect them from themselves. The purpose here is to provide the knowledge for solid decisions so that the proper code is used in the proper situations.

Update: Changing Alias Privacy to Protected Variable Pattern

Tags: , , , ,

17 Responses to “JavaScript: Private Variables are Evil”

  1. [...] View post: JavaScript: Private Variables are Evil « Club AJAX – Dallas Ft … [...]

  2. Mark Kawakami says:

    The way I see it, private functions and private variables in JS have a very specific place, and that place becomes more vital as developers do more unit testing and test driven development: It separates the public interface, which should remain stable and not break as you or your team modify the code during its lifetime from the inner workings of the code, which will inevitably change. You write your code and you write your tests (not necessarily in that order) and if your tests are thorough, you can say “this code is guaranteed to work”. Any future modifications to the code — refactoring or adding new funcitonality — will have to continue to pass those tests as well as whatever new tests you’ve added.

    Privacy allows you to define which parts of your code are not supposed to change from which parts of your code you can safely modify. This makes testing easier because you only have to test (and in fact, only can test) what is public. This also means you can refactor or enhance your code with greater confidence, because you can remove some function in your code that was never meant to be used outside of your widget without worrying that it will break some poor developer’s app (and heart).

    With your unit tests, you can guarantee that whatever changes you make, your code doesn’t break anything that used to work. And privacy helps you limit what needs to be tested. Good testing, a well defined public interface and judicious use of privacy keeps your code from becoming the unmaintainable, unwieldy house of cards we’ve all built sometime in our lives.

  3. Mike Wilcox says:

    @Mark

    Thanks for the comment and the insight. One thing I left out of the article was “duck-type privacy convention”. Dojo uses an underscore in front of methods and properties that are considered private or “use at your own risk”. One benefit of this convention is a developer could utilize that “private” method and then make a formal request to have that method standardized. The alternative could be a pretty big ugly rewrite.

    The _private() methods would be treated just as you say for unit tests.

  4. christian says:

    I agree with Mark on this one. It seems to me that your gripe is not private variables so much as it is bad design. Most of your examples illustrate bad design decisions, and blaming private variables is a bit like throwing out the baby with bathwater.

    For example, unique ids is a perfectly good use of private variables, as you don’t ever want someone to mess with the id variable. The mistake is making the function itself private. Used correctly private variables are excellent tools to hide implementation details.

    One last point is don’t mistake private variables for protected ones, which I believe was the mistake in the Dojo examples.

  5. Adrian Schmidt says:

    It seems to me that you take only bad examples and say “Look, these examples are bad”…
    I fully agree that using a private variable together with public getters and setters that do nothing is crap. There is just no reason to. But if the setter function does some evaluation before accepting and setting the value, I think the case is different, no?

    I understand your reasoning around “protecting yourself from yourself”, and I have had this feeling of useless privacy many times when building small apps (e.g. in school), where nobody else’s code will ever really interfere with mine. But isn’t Javascript one of the best examples of situations where you must always expect other people’s code to not only interfere, but possibly do so maliciously?

    What implications will this “unprivatized” coding practice have on the possibility for XSS? And what implications will it have on the risk that, for example, third party ads on the site might inadvertently break your scripts?

    Thanks for an interesting article!

  6. Mike Wilcox says:

    @Christian – Good point on the protected pattern. I’ll update the blog.

    You are correct that you could change the code, making not the method private, but the variable instead. And an id certainly seems like a safe enough use that privacy won’t hurt you. But it’s also rather innocuous isn’t it? What if you have a bug and need to inspect that id? It’s unlikely yes, because it’s so innocuous – but then what is important enough to make private and safe enough that you won’t need to touch it? You also say you “don’t want anyone to mess with the id”. I do emphasize a major point… that “anyone” is usually you. You don’t need protecting.

    @Adrian – Common! Are they bad or are they simple? :)

    As long as your code is properly namespaced, no other code should interfere. It’s a different topic but perhaps I should have included that in the post.

    As for XSS, if you find a way to protect your code with a private variable, that’s awesome, seriously. However if you are suggesting that you make *all* of your code private… ugh. Yeah it could be done but it would not be much fun to work with, and it would seem kind of paranoid. Maybe if you could make those cookies private and keep your XHR from being hacked you would have something cool.

    I don’t expect nor want to eradicate private variables from JavaScript. I just hope we all design our code a little more carefully.

  7. Christian says:

    About “protecting yourself from yourself”: I don’t buy into that as an argument for not using private state. First, one could easily use this argument as an excuse to write sloppy code all over the place, which I don’t think is very productive. Secondly, “yourself” is also “your self in two weeks, two months or a year”. You may not be so confident on code you wrote a while back. Carefully using private state where appropriate hides implementation details that should never be depended on from the outside. This helps both your future self, possible coworkers and whoever inherits your code down the road.

    Using private state also avoids other code accidentally introducing bugs to your code base, e.g. by typos or similar.

    The point on debugability is also not valid (in my eyes) if you have good unit tests for your code, which I strongly suggest you have. A strong test suite mostly eradicates the need for ad hoc Firebug debugging, and in the odd case where you need to inspect some private state, use a breakpoint debugger.

  8. Mike Wilcox says:

    Hey Christian,
    You can write sloppy code with or without privates, I certainly don’t advocate sloppy code. I don’t see the relevance. As a Dojo committer I do revisit year-old code, so it better be readable (and not sloppy).

    Really, I think you miss my point that you don’t have to make things literally private to make the code usable. I or anyone else should be able to see what the API is if it’s properly written, duck-typed, and namespaced. You don’t *have* to rely upon privacy which I argue does more harm than good. Privacy is for enterprise code, not web apps.

    You say never, like you can predict the future. Look at the early version of my FileUploader code (linked in the post). It had code that should have ‘never’ needed to be accessed. Yet about a year later I found myself rewriting it because while I, nor any dev needed to access those private properties, the closure did, which broke the inheritance.

    Nobody is arguing against unit tests. I don’t use them even though there are times I should (I use test cases). But unit tests prevent regressions, they can’t prevent unforeseen bugs. Privacy won’t prevent unforeseen bugs either.

  9. Christian says:

    I just meant that not “protecting yourself from yourself” can be used to argue for just about anything. Such as sloppy code; If I’m the only one working on the code base, and I know the code well, then I can spaghetti code all I want, cause I don’t need protection from my own bad routines? Perhaps it’s a bit far fetched, but I’m not buying “don’t protect yourself from yourself”.

    Also, I don’t mean to advocate excessive use of private state. I use it sparingly, for implementation details. Looking at your original FileUploader, I see several uses of private stuff that aren’t merely implementation details, but generally useful stuff, and some stuff that probably was intended to be protected – i.e. invisible from the outside, but reachable for extensions, which isn’t really possible.

    Anyway, most of your issues are completely valid, but I think the reasoning is not entirely accurate. Nonetheless, interesting discussion :)

  10. [...] more here: JavaScript: Private Variables are Evil « Club AJAX – Dallas Ft … If you enjoyed this article please consider sharing [...]

  11. Rakesh Pai says:

    Nitpicking, but consider the following code:

    this.getWidth = function(){
    return width + this.borderWidth*2;
    }

    It will always break since “this” in this.borderWidth will refer to the function’s scope, whereas borderWidth is defined in the scope outside. You’ll either have to call getWidth by apply-ing it to the object scope, or use the Crockford var that = this; trick.

  12. Mike Wilcox says:

    Hi Rakesh,

    A function’s context is determined by the object which invoked it. Or simply put, in most cases it’s the object preceding the function: **object.function = function(){}. In this case the context is “this” or the object instance created, which also is in the same _scope_ as the width variable (argument).

    Using “var getWidth” would not have worked, as you say.

  13. Duarte Cunha Leão says:

    I understand your view about privateness but, honestly, I don’t share the same view.
    I see privateness in JavaScript, or in any other programming language, as a way to achieve the encapsulation in OO design.
    Anyway, I’m not writing to “hurt” your opinion. Rather, I would like to share with you a pattern I found that enables any JavaScript object to hold private state with it, using normal public methods (not the privileged methods and private constructor variables pattern).
    Hope you’ll find some good use for it, even if it’s just a pedagogic one!
    http://www.codeproject.com/KB/ajax/SafeFactoryPattern.aspx

  14. Barry Maneza says:

    I just started looking at the new jPaq javascript library. The creator, Chris West, seems to have found a way of allowing prototype functions to access the private variables. He did this with his Color class. The reason this is such a big breakthrough is cuz it prevents you from having thousands of duplicate functions if you have thousands of instances of a specified class (such as the Color class). Build a library with this Color class and download it from http://jpaq.org/ . To tell you the truth, I am suprised Chris hasn’t made a big deal about this.

  15. Mike Wilcox says:

    @Barry Maneza: Actually, Chris’ privacy pattern confirms my belief that privacy patterns provide nothing more than to complicate what should be simple code. He’s hiding the functions that return the rgb values – why? What would I break? And if I did so what? If I red line the speedometer in my car and wrap it around a light pole should I complain that they didn’t hide the accelerator from me?

    If using functions within a prototype, you would not have thousands of functions – you would have three (in the case of r(), g(), b() anyway) – and if you had a thousand objects, they would all reference those three functions, but within the context of the different object’s instance. That’s how you conserve memory in JavaScript.

    Great link though. Chris West’s library has a great concept there with the function ala’ carte. Tweeting that!

  16. blerik says:

    Privacy is very important if you work with more people. If you don’t hide the internals of what you are building, the other guy(s) will find a way to hook into it, and then you cannot change it anymore without breaking the build. I admit that this can be solved by agreeing to respect _variable or _method names as private, but when the deadline comes close, someone will still hook into your internals and bind your hands like that. Privates enforce API’s and that keeps everybody honest.