Private Slots

David Bruant bruant.d at gmail.com
Mon Jan 14 08:37:47 PST 2013


Le 14/01/2013 16:57, Kevin Smith a écrit :
> When a property is added to an object using a private symbol, it 
> creates a new kind of slot:  a private slot.  It is clear from the 
> design of the Proxy API that this represents a fundamentally new 
> extension to the ES object model.
>
> On the very first paragraph of the CoffeeScript homepage, we read:
>
> > Underneath all those awkward braces and semicolons,
> > JavaScript has always had a gorgeous object model at
> > its heart
Nothing against CoffeeScript, but the Coffeescript homepage doesn't hold 
for the unique source of truth about JavaScript.
My personal take on the ES5 object model with property descriptors and 
[[Extensible]] is that it's a way too complicated model. But that's a 
necessary one given history, the DOM, the need to fix the platform 
underneath your feet, etc.

> It seems to me that any changes or extensions to the ES object model 
> should be justified by well-documented application-focused use cases, 
> clearly illustrating the need for such a change.
Per-instance private state always come with absurd costs in the ES5 model.

     function C(){
         var s = String(Math.random()).substring(2);

         this.firstLetter = function(){
             return s.substring(0, 1);
         };
     }

In this case, each instance has its own method (each function has its 
own well-encapsulated scope), costing memory. This shouldn't be necessary.

It's also possible to have the method inherited:

     function C(){
         this.init();
     }

     var states = new WeakMap();
     C.prototype = {
         init: function(){
             var state = {s: String(Math.random()).substring(2)};
             states.set(this, state);
         },
         firstLetter(){
             var state = states.get(this);
             return state.s.substring(0, 1);
         }
     }

There is some boilerplate (all the weakmap game) making the code less 
easily readable and runtime costs (at least memory, because one 
additional state object is created per instance!) to this kind of 
solutions too. The additional state object will also cost something in 
terms of GC.

I was obviously talking about actually private state, not _properties, 
which have no additional runtime cost, but are also not private at all!

Let's see with symbols:

     var sym = new Symbol();
     function C(){
         this[sym] = String(Math.random()).substring(2);
     }
     C.prototype = {
         firstLetter: function(){
             return this[sym].substring(0, 1);
         }
     }

No boilerplate, no additional runtime costs than what's necessary.

> I would personally like to see answers to the following questions:
>
> - Do private slots enable applications that would otherwise be impossible?
I guess applications where you need memory for your actual content and 
not memory to compensate the lack of language expressiveness. I have no 
real idea of how much can be saved in terms of memory between the 3 
snippets I've shared with millions of C instances.

> - What are some examples of real-world applications where the runtime 
> security of private slots is necessary?
It really depends on what you mean by "necessary". As far as I'm 
concerned, it'd be all application using third-party code and a lot of 
websites embed a Google Analytics script, so that would be a lot of them 
(looking forward to the day GA is being hacked by the way :-) )

> - In those applications, are there acceptable methods of achieving the 
> same results which do not rely on extending the object model?
I showed 2 alternatives. Whether they are acceptable depends on whether 
you'll fill the runtime memory up to crashing it. For most cases, it 
won't be the case, I agree.

> - If GC performance is a significant motivator, then can this supposed 
> benefit be quantified?
I don't feel qualified to answer this point.

 From the teachability perspective, I'm tired of explaining the closure 
hack to explain "private" properties. Even to some who are experienced 
webdevs, I have to explain that they can't access the "private" property 
through "this.".
The language needs to evolve to the point where people can write 
"this[something]" to retrieve private state. Symbols work for that.

David


More information about the es-discuss mailing list