Ducks, Rabbits, and Privacy
nathan.wall at live.com
Tue Jan 22 07:17:33 PST 2013
Kevin Smith wrote:
> In ES5, there is no distinction between "public" and "private" data within
> an object. If you want to create private data, you must do so using a
> closure. All private data is therefore "external" to the object in
> question. The data does not "follow" the object around. This is a simple
> model. It is easy to reason about. It's not clear that this model is
> insufficient for our needs.
I have enjoyed the many conversations revolving around WeakMaps & symbols very much, and in the scheme of things I'll be just fine without private symbols (I've made it without them so far). However, I do disagree that it's easy to reason about data in ES5. I do think that it's insufficient, and I would point to the spec itself as evidence that the concept of "private" data significantly improves reasoning when dealing with objects.
The ES5 spec describes built-ins as having "private" data associated with each object (you know those [[InternalProperties]]). It would be perfectly possible for the spec to describe the behavior of built-ins without referring to "private" properties, but the spec uses this model because it is the most convenient model. Yet, ES5 does not provide any means within the language for developers to tie "private" data to objects. (It's always been a strange facet of the ES language that built-ins are able to be more magical than user-defined objects.)
If it was such a simple model to do without "private" data, my questions would be (1) Why does the spec itself not do without the concept when describing built-ins? (2) Why do so many developers use underscore properties to *simulate* private data? (3) Why do other developers abandon prototypal inheritance and build their objects inside constructors so that they can have private data?
It's my opinion that saying that closures should be used for an object to hold onto private data, as you are advocating, is in conflict with ES's prototypal model of inheritance. Methods cannot both (A) be on a constructor's prototype and (B) live inside the scope used to house private data. The developer is forced to make a decision: Do I want my methods to be defined on the constructors prototype or do I want them to have access to private data?
The fact that ES built-ins' methods are defined on the prototype **and** have access to private data seems to indicate that the ideal model would allow both. WeakMaps do, to a degree, permit both, but it's just a hack. If it wasn't, the ES spec itself would describe built-ins' private data as living outside the object itself in a WeakMap. The spec doesn't do that because it's unnatural. Private symbols provide a mechanism for tying private data to objects in the most natural and reasonable way.
More information about the es-discuss