Gentleman’s Privates
Saturday, February 25th, 2006In Javascript, you can have true private methods and fields, but it comes at a cost…both a readability cost and a performance cost. It basically involves creating closures in the constructor. Those closures are attached to ‘this’ reference and since they are closures defined in the scope of the constructor, they have access to any of the constructor’s local variables. An example may prove useful:
function Foo(){
var privateField = “Only setPrivate and getPrivate can see this field”;
this.setPrivate = function(value){
privateField = value;
}
this.getPrivate = function(){
return privateField;
}
}
I first learned about this over at Douglas Crockford’s site (this guy knows his stuff…read it!). He as great explanation of private members in javascript.
At the moment (and I’m sure this can change) I feel this is a bit overboard for most cases. I think I may be more turned-off by the readability…I just can’t bring myself to be ok with having the methods defined IN the constructor. I understand this is the only way to have TRUE private members…but I’m thinking that I’d be ok with Gentleman’s Privates. That is to say, using a notation that tells the user (developer using, reusing, extending or otherwise interacting with the class or an instance of the class) that the variable is meant to be private…”so, be a gentleman and don’t access it directly”. Sure, this leaves the door open for abuse…breaking encapsulation. But if the convention is known…then the developer KNOWS they shouldn’t be directly accessing the variable (even though the language doesn’t enforce it). And by doing so, they run the risk of becoming too tied to that implemenation of the class.
Naming conventions for private members is done all over the place…even in languages that support true private members (no I don’t). I can’t find it with a quick google, but I’m sure I first heard this approach in reference to Perl. It was something to the effect of describing Perl as a “Gentlemen’s Language”. Basically meaning that the language didn’t enforce any access restrictions, but the developers were ‘gentlemen’ about it, and followed the rules of the naming conventions. The typical convention for private members (as I understand it) is to prefix the variable with an ‘_’ character. In my experience, many developers understand this convention.
I prefer the Gentlemens approach to private members in javascript.  I don’t want to get hung up on trying to lock my object/class down to prevent any abuse: jumping through hoops trying to get access priveleges that are not enforced by the language. Let’s just be gentlemen about it.
Ok, all that said, I was thinking a bit about the naming convention itself. The ‘_’ prefix is well known, so it’s tough to just say ‘lets change it’, but I’m thinking…’lets change it’. How about ‘ _’? That is SPACE-Underscore…as a prefix for private members. This forces the developer to access the member via the bracket notation: obj[’ _somePrivate’]. This has a few benefits in my mind. First, it isn’t natural which means you’ll have to think about it and say “well…it IS private…maybe I should try something else”. Second, its not pretty…so a developer may decide to modify the design (if its his code) so that the member is exposed, or it supports whatever the caller was trying to do via a new method.
The negatives are actually the same as the benefits…but the caller is the class code itself. So the class has to access its private members through the same bracket notation, which is still not natural, and still not pretty. Given that the private members should (by definition) only be accessed by the owning class, this may seem like just an annoyance and may find developers quickly abandoning it.
In the end…I guess I’m up in the air about it. I like that it will make it more work for developers to access it when they shouldn’t (from outside the owning class)…but I don’t like that it will also be more work for developers to access it when the can/should (from inside the owning class). And in the end, maybe ‘_’ should send up the same flag to the developer as “[’ _’]”.
What are some of your thoughts?