hattenn hattenn - 5 months ago 13
Javascript Question

Using closures or the underscore convention for private members

Douglas Crackford and many others suggest using closures for private members as follows:

function Container(param) {

function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}

this.member = param;
var secret = 3;
var that = this;
}


The upside of this is that these members are not accessible outside the constructor function, but the downside is that it's not possible to use the private members in the prototype. So you end up putting everything that uses the private members in the constructor, which is not good for memory purposes.

Some others recommend using underscores when naming the private members:

function Container(param) {
this.member = param;
this._secret = 3;
}

Container.prototype.dec = function {
if (this.secret > 0) {
this.secret -= 1;
return true;
} else {
return false;
}
}


The downside of this is that those members are easily accessible publicly, and the only thing stopping people is the convention.

My questions are:


  1. When do you decide to use one over the other?

  2. Is one way preferred more commonly than the other?

  3. What are some famous libraries that use one of these methods?

  4. Is there a better method than these two?


Answer

As you have already outlined, there are tradeoffs between these two methods. So, which to use depends entirely upon the specifics of your use cases and there is no answer that doesn't consider the actual use cases. You can bound the decision a few ways:

If you are making tens of thousands of these objects, then perhaps the increased memory usage of not using the prototype is meaningful and you might want to sacrifice true privacy in order to manage your memory usage and use the prototype version that doesn't have real privacy. If you're not making large numbers of objects or running in a very compact memory footprint, the memory usage difference is unlikley to matter.

Crockford makes a case that the memory issue is rarely a real issue these days. But, I think that's just a general statement and you have to evaluate your particular situation to know whether that's true or not.

If privacy is paramount and you absolutely don't want outsiders mucking with internal private variables (perhaps it's even a security thing from an API or a reliability issue), then by all means choose the closure option that gives you real privacy.

When do you decide to use one over the other?

It depends upon what you most want to optimize for and the best choice is specific to the use case.

Is one way preferred more commonly than the other?

It depends upon what you most want to optimize for and the best choice is specific to the use case.

What are some famous libraries that use one of these methods?

jQuery uses a mixture of these. It has some "non-public" properties that start with an underscore. And, it uses some closure variables that are truly private, though generally only for objects of which there are only one or a small number of or sometimes just for module-level globals. Over time, it appears to me that jQuery has switched some of its _priv properties to more protected closure variables, but still has some of each.

This is likely because jQuery is trying to optimize memory use for a jQuery object itself and thus doesn't want to create an extra closure or use extra memory for methods. But, for other types of objects it uses where there are not so many, it can more easily afford the extra memory usage for true privacy.

Is there a better method than these two?

Closures are the best scheme I've seen for true privacy. If you're not using a closure, the only other means of indicating non-public is by convention and the leading underscore is the more common convention for doing so.

Comments