Well keep in mind that Symbols of any type already require using a new function, getOwnKeys (or whatever the name is) so they are already essentially "super non-enumerable". They are reflectable if someone really wants to see them, but they are never reflected in Object.keys, Object.getOwnPropertyNames, or for...in enumeration.
On Thu, Jan 17, 2013 at 12:32 PM, Axel Rauschmayer <[email protected]> wrote: > Can we separate of concerns? > > 1. I love symbols. > > 2. I also love the idea that you can mark properties as private, as > invisible to the outside. Currently I prefix my properties with `_` to do > so, but it’s an ugly namespace pollution. > > 3. But, for me and probably most applications, the privacy does not have > to be bullet proof. For the rare cases where we need. bullet-proofing, weak > maps might be enough. > > 4. Enumerability still seems like something that only exists because for > for-in. Unfortunately, it can’t take up role #2, because so many things are > already non-enumerable that are clearly public. > > Does that mean that the current ES6 model could be simplified? For > example: another property attribute `visible`, making properties invisible. > Not sure where the invisibility matters: at an IDE level, when you do an > expansion (e.g. type `myobj.`). Or should it also be hidden from all > current iteration operations (Object.getOwnPropertyNames() etc.)? In either > case, there would still be a way of iterating over all properties, making > copying etc. straightforward. > > > On Jan 17, 2013, at 18:00 , "Mark S. Miller" <[email protected]> wrote: > > First, I agree with David that security is important, both for > security per se and for modularity in general. ES5 improved the > language when it fixed the accidental leaks between the world of > objects and scope-chain objects, like thrown functions. ES5/strict > improved the language when it made functions really encapsulated, > poisoned caller and arguments, and repaired the remaining violations > of static scoping. ES6 modules and CommonJS/Node modules were born and > remain encapsulated. I have not heard anyone suggesting any of these > would be improved by introducing pliers for opening them against their > will (except in a debugger, which is a different issue). Tons of code > have been written in ES3. We still made the world a better place when > we plugged its leaks. > > I also agree with David that unique symbols are not an encapsulation > mechanism, but rather, merely a mechanism to avoid namespace > collisions. > > As for Java's reflective breakage of "private", > < > http://www.nbcnews.com/technology/technolog/us-warns-java-software-security-concerns-escalate-1B7938755 > >. > > > However, after the "Private Slots" thread, I spent a sleepless night > chewing on getting rid of private symbols. I now think we should. > Going back to my earlier > > > On Wed, Jan 16, 2013 at 12:37 PM, Mark S. Miller <[email protected]> > wrote: > > My position on private symbols. > > My position on classes is and has always been that classes are worth > introducing into the language *only* if they give us, or can be used > with, an affordable means for true object encapsulation. Assuming > Allen is right about what actual implementors will do (which I find > plausible) then WeakMaps are not that means. > > > I still have this position on classes. But I no longer buy that > pessimistic conclusion about WeakMaps. Consider how WeakMaps would be > used by the expansion of classes-with-private. Just 'cause it's on the > top of my head, below I use the old representation of one WeakMap per > class providing access to a record of all the private state. For the > same reason, I'll use the encapsulation of the Purse example without > any of the numeric checks. > > class Purse { > constructor(private balance) { > getBalance() { return balance; } > makePurse() { return Purse(0); } > deposit(amount, srcPurse) { > private(srcPurse).balance -= amount; > balance += amount; > } > } > > expansion > > let Purse = (function() { > let amp = WeakMap(); > function Purse(balance) { > amp.set(this, Object.seal({ > get balance() { return balance; }, > set balance(newBalance) { balance = newBalance; } > })); > } > Purse.prototype = { > getBalance: function() { return balance; }, > makePurse: function() { return Purse(0); }, > deposit: function(amount, srcPurse) { > amp.get(srcPurse).balance -= amount; > } > } > return Purse; > })(); > > > Ignore the issues about whether we should use one WeakMap per class > and a private record as above, or a WeakMap per private field name > declaration. > > Ignore the use of accessors so that private field names track > variables. If we had instead stored the state in the private field and > compiled getBalance to use the field, that doesn't affect the > important issue. > > > > ********************** > Notice that the lifetime of amp cannot be shorter than the lifetimes > of the Point instances, since the instances retain amp, and these > instances are the only objects ever stored as keys in amp. > ********************** > > > > For this usage common pattern, the lifetime of the keys of amp cannot > outlive the lifetime of amp. > > Thus, no matter what the spec says, normatively or not, about expected > storage costs, competitive pressures will drive JS engine implementors > to make this efficient. The way to make this efficient is by the > technique previously discussed -- hang the private state off of the > object, not the weakmap. Use the weakmap only as an unforgeable token > for naming and accessing this state. If we get rid of private symbols, > we should expect this pattern of usage of WeakMap to have the same > cost that private symbols would have had. We can help implementors > achieve that by having this expansion call instead > "WeakMap(USE_KEY_LIFETIME_HINT)" or whatever it is called. Then > implementations would not have to recognize the pattern by other > means. > > Complexity is the enemy of security. We already have four > encapsulation mechanisms in ES6 in addition to private symbols: > 1) functions encapsulating lexical variables > 2) WeakMaps > 3) proxies encapsulating handlers and targets > 4) modules encapsulating what they don't export. > > With enough spec and engineering effort, any of these could be grown > into a means for providing efficient class/object encapsulation. Of > them, I think #2 is most plausible. Even is we find #2 does not work > out, we should think about growing one of the other candidates as an > alternative to private symbols. Security demands simplicity, and > semantic simplicity is more important than implementation simplicity. > > > > -- > Cheers, > --MarkM > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss > > > -- > Dr. Axel Rauschmayer > [email protected] > > home: rauschma.de > twitter: twitter.com/rauschma > blog: 2ality.com > >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

