I'm aware it's possible to misuse, but if concerns of misuse were a serious issue, we wouldn't have iterators, for example [1] [2]. But IMHO freeing weak maps from a role they weren't designed for substantially outweighs the risks of abusing them further (and the abuses are incredibly frequent).
[1]: https://esdiscuss.org/topic/iterators-generators-finally-and-scarce-resources-was-april-10-2014-meeting-notes [2]: https://esdiscuss.org/topic/resource-management ----- Isiah Meadows m...@isiahmeadows.com www.isiahmeadows.com On Sun, Jul 29, 2018 at 10:55 PM, Michael Theriot <michael.lee.ther...@gmail.com> wrote: > Right, I wouldn't, but I'm concerned others would misuse it. I don't think > it's a blocker though, and actually frees weakmaps from trying to fill this > role. > > > On Sunday, July 29, 2018, Isiah Meadows <isiahmead...@gmail.com> wrote: >> >> It will, but weak maps will still remain useful for cases when you're >> semantically dealing with a key/value map. In theory, you could >> implement a weak map on top of this [1], but in practice, it doesn't >> always make sense to do it. A good example of this is if you are >> "tagging" an object with data. If this data isn't really part of the >> object itself, you shouldn't be using a private symbol for it. Another >> good example is if you're doing simple caching and you need to clear >> the weak map by replacing it. Using private symbols for this doesn't >> really fit with the domain here, so you're more likely just to confuse >> future readers (including yourself) if you do this. >> >> [1]: https://gist.github.com/isiahmeadows/a8494868c4b193dfbf7139589f472ad8 >> ----- >> >> Isiah Meadows >> m...@isiahmeadows.com >> www.isiahmeadows.com >> >> >> On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot >> <michael.lee.ther...@gmail.com> wrote: >> > Private symbols sounds like an easy win. They would be painfully simple, >> > real properties, not just variables with property imitation syntax that >> > undoubtedly confuses people. With the added benefit that children can >> > truly >> > override the base class, freedom to define private members shared across >> > otherwise unrelated objects, and even injection. My only concern is that >> > it >> > could cross into WeakMap use cases. >> > >> > >> > On Sunday, July 29, 2018, Isiah Meadows <isiahmead...@gmail.com> wrote: >> >> >> >> BTW, I came up with an alternate proposal for privacy altogether: >> >> https://github.com/tc39/proposal-class-fields/issues/115 >> >> >> >> TL;DR: private symbols that proxies can't see and that can't be >> >> enumerated. >> >> ----- >> >> >> >> Isiah Meadows >> >> m...@isiahmeadows.com >> >> www.isiahmeadows.com >> >> >> >> >> >> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine >> >> <valentin...@gmail.com> wrote: >> >> >> What you're essentially asking for is a violatable private field, or >> >> >> as >> >> >> has been described by others, a "soft private". >> >> > >> >> > We might have different definitions here, but I would describe what >> >> > I’m >> >> > talking about as hard private. Soft private, at least as it appears >> >> > to >> >> > have >> >> > been defined in [prior >> >> > >> >> > discussions](https://github.com/tc39/proposal-private-fields/issues/33), >> >> > described an avenue where symbol keyed properties were given a new >> >> > syntactic >> >> > form — but they were still just regular symbol keys, and therefore >> >> > could >> >> > be >> >> > introspected by outside agents who had not been given express >> >> > privilege >> >> > to >> >> > do so: >> >> > >> >> >> [...] the core would be that "private state" is simply (public) >> >> >> symbol-named properties, with syntactic sugar for those symbols, and >> >> >> possibly some kind of introspection over them [...] >> >> > >> >> > The thread goes on to contrast the soft model with an earlier version >> >> > of >> >> > the >> >> > private fields proposal seen today. The hard private example uses the >> >> > class >> >> > declaration as a pseudo-scope, but contrasting these two options as >> >> > if >> >> > they >> >> > are binary is not accurate: hard private through >> >> > module/function/block >> >> > scope >> >> > already exists, it is just difficult to work with in the context of >> >> > shared >> >> > prototypes — one must either use WeakMaps, technically giving >> >> > _hardness_ >> >> > because of the forgeability of `global.WeakMap` / `WeakMap.prototype` >> >> > / >> >> > `WeakMap.prototype.get|has|set`, or be willing to either not worry >> >> > about >> >> > garbage collection or implement it manually. This could be solved for >> >> > with a >> >> > few rather undramatic changes, though. >> >> > >> >> > Notably, the first post there lists the following as a disadvantage >> >> > of >> >> > the >> >> > soft model it describes: >> >> > >> >> >> Platform objects, both within ECMAScript and in embedding >> >> >> environments, >> >> >> contain hard private state. If a library wants to be high-fidelity >> >> >> and >> >> >> just >> >> >> like a platform object, soft-private state does not provide this >> >> >> (@domenic) >> >> > >> >> > ...but neither model there quite covers that use case. Platform >> >> > objects >> >> > _can_ see each other’s private state (cf the `isView` example >> >> > earlier, >> >> > or >> >> > scan the DOM API specs / Chrome source a bit to find numerous >> >> > examples). >> >> > It’s only the ES layer interacting with their interfaces that cannot. >> >> > >> >> > Such things can be achieved with ordinary scope, which is why the >> >> > WeakMap >> >> > pattern has worked in practice in my experience to date, while >> >> > class-declaration-scoped privacy has not. It isn’t uncommon for a >> >> > library’s >> >> > exposed interface to be composed of an object graph, where privacy is >> >> > a >> >> > concern at this public interface level, but library internal state >> >> > may >> >> > be >> >> > interconnected in unexposed ways under the hood. The most familiar >> >> > example >> >> > of this is a DOM node tree. As an experiment, perhaps try to >> >> > implement >> >> > the >> >> > relationships between HTMLFormElement, HTMLFormControlsCollection and >> >> > the >> >> > various form control elements using either the main private fields >> >> > proposal >> >> > or your alternative proposal and see what happens. >> >> > >> >> >> However, the guardian logic tries to verify that the function trying >> >> >> to >> >> >> access the private fields of an instance is a member of the same or >> >> >> descending prototype that was used to create that instance. >> >> > >> >> > Because I’m looking at this in terms of slots, I’d first point out >> >> > that >> >> > prototypes don’t determine slottedness, the execution of some >> >> > specific >> >> > constructor does. It’s during this process that slots are associated >> >> > with >> >> > the newly minted object by its identity. But even the current private >> >> > fields >> >> > proposal tracks this behavior closely, and I’m not sure how else it >> >> > could >> >> > work. The [[Prototype]] slot of an object is typically mutable >> >> > (`R|O.setPrototypeOf`, `__proto__`) and forgeable (Proxy’s >> >> > `getPrototypeOf` >> >> > trap). Why/how would its value matter when it comes to accessing >> >> > private >> >> > state? >> >> > >> >> > ```js >> >> > const pattern = /foo/; >> >> > Reflect.setPrototypeOf(pattern, Date.prototype); >> >> > pattern instanceof Date; // true >> >> > pattern instanceof RegExp; // false >> >> > pattern.getMinutes(); // throws TypeError because [[DateValue]] slot >> >> > is >> >> > missing >> >> > RegExp.prototype.exec.call(pattern, 'foo'); // works; object has >> >> > RegExp >> >> > private slots >> >> > ``` >> >> > >> >> >> If I removed that requirement, it would work. However, there'd be no >> >> >> way >> >> >> to keep the private data from being leaked. Sadly, it's all or >> >> >> nothing >> >> >> with >> >> >> this approach. Hard private or soft private, those are the only >> >> >> choices. >> >> > >> >> > In the context of what you’ve described here this may be true, but no >> >> > such >> >> > limitation presently exists. We can already do all this — hard, >> >> > leak-free >> >> > privacy, brandedness, “friends” etc — with scopes and WeakMaps, but >> >> > for >> >> > the >> >> > fact that the `WeakMap` intrinsics may be forged. So what’s baffled >> >> > me >> >> > is >> >> > this: why are all the proposals exploring this space not addressing >> >> > that >> >> > relatively simple existing problem, and instead starting off from a >> >> > place of >> >> > significant new complexity? You said “maybe after the private fields >> >> > problem >> >> > has been resolved, someone will figure out a better way to handle >> >> > your >> >> > use >> >> > cases,” but I’d have hoped for the opposite — I want the primitive >> >> > building >> >> > blocks which things like class field syntax could be built over, if >> >> > it >> >> > is >> >> > found that they are still necessary once the root issue is solved >> >> > for. >> >> > >> >> >> The main reason the privacy is set on a declaration level is because >> >> >> scope-level inheritance isn't very good for class-oriented >> >> >> inheritance. >> >> > >> >> > Can you explain this more? I’m not sure what’s meant by “scope-level >> >> > inheritance” here. >> >> > >> >> >> I don't intend to stop [...] >> >> > >> >> > I very much admire your dedication! I’m also digging the discussion. >> >> > I >> >> > think >> >> > we may be representing viewpoints at opposite extremes here, so it’s >> >> > an >> >> > interesting contrast, but it also probably means we may be lacking >> >> > some >> >> > context for understanding one another’s angles. I’d be curious to >> >> > hear >> >> > more >> >> > about what you see as the problems with the current fields proposal + >> >> > how >> >> > your members proposal would solve them; the repo readme didn’t seem >> >> > to >> >> > include a rationale section. >> >> > >> >> > On Sat, Jul 28, 2018 at 10:30 PM Ranando King <king...@gmail.com> >> >> > wrote: >> >> >> >> >> >> I've almost given up on making any significant headway in either >> >> >> adjusting >> >> >> or flat-out correcting the flaws in that proposal, but I don't >> >> >> intend >> >> >> to >> >> >> stop trying until either we get stuck with that proposal, or they >> >> >> understand >> >> >> and accept what I'm telling them, or logically prove that my >> >> >> concerns >> >> >> are >> >> >> either irrational or inconsequential. >> >> >> >> >> >> > Private object state in particular is only _made complex_ by >> >> >> > associating >> >> >> > it with declarations instead of scopes that happen to contain >> >> >> > declarations >> >> >> > (or into which constructors are passed, etc). The complexity is >> >> >> > artificial — >> >> >> > not a good sign imo. >> >> >> >> >> >> That's not quite right. What you're essentially asking for is a >> >> >> violatable >> >> >> private field, or as has been described by others, a "soft private". >> >> >> Since >> >> >> we agree that the "friendly" & "befriend" pair is a somewhat (if not >> >> >> completely) bad idea, I'm going to take 1 more pass at your 3 >> >> >> requests >> >> >> with >> >> >> a different angle. >> >> >> >> >> >> > Adding the same “slot” to multiple classes which don’t inherit >> >> >> > from >> >> >> > each >> >> >> > other >> >> >> > Selectively sharing access to private state through functions >> >> >> > declared >> >> >> > outside the class body >> >> >> >> >> >> ```js >> >> >> //Using my proposal >> >> >> var {A, B, C} = (() => { >> >> >> const common = Symbol("common"); >> >> >> >> >> >> class A { >> >> >> private [common] = 1; >> >> >> add(...args) { >> >> >> var retval = this#[common]; >> >> >> for (let obj of args) { >> >> >> retval += obj#[common]; >> >> >> } >> >> >> return retval; >> >> >> } >> >> >> } >> >> >> class B { >> >> >> private [common] = 2; >> >> >> optional() { >> >> >> console.log(`common member = ${this#[common]}`); >> >> >> } >> >> >> } >> >> >> var C = { >> >> >> private [common]: 3, >> >> >> required() { >> >> >> console.log(`common member = ${this#[common]}`); >> >> >> } >> >> >> } >> >> >> >> >> >> return { A, B, C }; >> >> >> })(); >> >> >> >> >> >> //So you want the following statement to not throw a TypeError and >> >> >> return >> >> >> 6 >> >> >> (new A()).add(new B(), C); >> >> >> ``` >> >> >> I'm not sure I can make this work in my proposal, and I'm absolutely >> >> >> sure >> >> >> you'd be flatly refused by the other proposal. If a `Symbol` is >> >> >> provided as >> >> >> the `[[IdentifierName]]` of a private or protected field, then I can >> >> >> let >> >> >> that `Symbol` be both the key and value that are added to the >> >> >> `[[DeclarationInfo]]` and `[[InheritanceInfo]]` records. That way >> >> >> there >> >> >> will >> >> >> be a common private field name usable by all 3 objects. However, the >> >> >> guardian logic tries to verify that the function trying to access >> >> >> the >> >> >> private fields of an instance is a member of the same or descending >> >> >> prototype that was used to create that instance. If I removed that >> >> >> requirement, it would work. However, there'd be no way to keep the >> >> >> private >> >> >> data from being leaked. Sadly, it's all or nothing with this >> >> >> approach. >> >> >> Hard >> >> >> private or soft private, those are the only choices. The TC39 board >> >> >> has >> >> >> already decided that what they want new syntax for is hard private. >> >> >> >> >> >> > Adding slots dynamically, e.g. when adding mix-in methods that may >> >> >> > initialize a new slot if necessary when called, since subclassing >> >> >> > is >> >> >> > not >> >> >> > always appropriate >> >> >> >> >> >> Because the TC39 board has set their sights on hard private, this >> >> >> will >> >> >> require new syntax like what I suggested earlier Adding private >> >> >> members >> >> >> dynamically would also pose a leak risk if it could be done after >> >> >> the >> >> >> prototype has been fully constructed. The main reason the privacy is >> >> >> set on >> >> >> a declaration level is because scope-level inheritance isn't very >> >> >> good >> >> >> for >> >> >> `class`-oriented inheritance. The `class` keyword was provided to >> >> >> simplify >> >> >> the vertical inheritance model, along with some API to enable >> >> >> inheritance >> >> >> from native objects even without using `class`. The syntax changes >> >> >> for >> >> >> simplifying private field declaration are just an extension of that. >> >> >> Even >> >> >> though it's not unusual for some developers to spend a lot of time >> >> >> working >> >> >> with fringe use-cases, syntax changes are almost always going to be >> >> >> made for >> >> >> the most common use cases first. Maybe after the private fields >> >> >> problem >> >> >> has >> >> >> been resolved, someone will figure out a better way to handle your >> >> >> use >> >> >> cases. >> >> >> >> >> >> >> >> >> On Sat, Jul 28, 2018 at 3:52 PM Darien Valentine >> >> >> <valentin...@gmail.com> >> >> >> wrote: >> >> >>> >> >> >>> > Are you saying you want multiple non-hierarchally related classes >> >> >>> > to >> >> >>> > have an instance private field with shared name [...] >> >> >>> >> >> >>> Yeah. This is a hard problem to solve when trying to integrate >> >> >>> private >> >> >>> fields with class syntax, but it’s not a problem at all when >> >> >>> privacy >> >> >>> is a >> >> >>> more generic tool based on scope. This also isn’t a foreign concept >> >> >>> in >> >> >>> ES: >> >> >>> consider this intrinsic method: >> >> >>> >> >> >>> https://tc39.github.io/ecma262/#sec-arraybuffer.isview >> >> >>> >> >> >>> This method returns true if the argument has the >> >> >>> `[[ViewedArrayBuffer]]` >> >> >>> slot. This slot exists on genuine instances of both `%TypedArray%` >> >> >>> and >> >> >>> `%DataView%`, but they do not receive these slots by way of >> >> >>> inheritance from >> >> >>> a common constructor. There are similar cases in HTML host APIs. >> >> >>> >> >> >>> > The befriend keyword would allow an object to request friendship >> >> >>> > with >> >> >>> > an existing friendly object. I'm not sure this is a good idea, >> >> >>> > though. >> >> >>> >> >> >>> I don’t think it is either, no. It’s too much complexity for too >> >> >>> little >> >> >>> gain. But again, this is achievable “for free” just by divorcing >> >> >>> “private >> >> >>> object state” from class declarations (or object literals). I would >> >> >>> ask: >> >> >>> what problem is solved by making this a feature of the declarations >> >> >>> themselves? Does it merit the complexity and the hoop jumping >> >> >>> needed >> >> >>> to >> >> >>> handle edge cases?\* >> >> >>> >> >> >>> \* One person’s edge case; another’s everyday concern haha. >> >> >>> >> >> >>> > The example you gave above still declares the functions in >> >> >>> > question >> >> >>> > inside the class body, so that's not really a solution. >> >> >>> >> >> >>> If you’re referring to the first example, that is a demonstration >> >> >>> of >> >> >>> what >> >> >>> is possible using the existing stage 3 class fields proposal as >> >> >>> implemented >> >> >>> in Chrome. It isn’t what I want; it’s what’s necessary to achieve >> >> >>> this >> >> >>> with >> >> >>> the current stage 3 proposed model. >> >> >>> >> >> >>> > Sounds to me like you'd love for class syntax to look like this >> >> >>> > [[example with mixin syntax in declaration]] >> >> >>> >> >> >>> Perhaps — it’s interesting for sure! But the pattern that already >> >> >>> works, >> >> >>> `mixin(Cstr)`, is not presently a source of problems for me. >> >> >>> Private >> >> >>> object >> >> >>> state in particular is only _made complex_ by associating it with >> >> >>> declarations instead of scopes that happen to contain declarations >> >> >>> (or >> >> >>> into >> >> >>> which constructors are passed, etc). The complexity is artificial — >> >> >>> not a >> >> >>> good sign imo. >> >> >>> >> >> >>> > One thing both proposal-class-fields and proposal-object-members >> >> >>> > have >> >> >>> > in common is that the focus is on producing instance-private >> >> >>> > fields. >> >> >>> > All 3 >> >> >>> > of the scenarios you presented lay outside of that focus for one >> >> >>> > reason or >> >> >>> > another. >> >> >>> >> >> >>> Both the WeakMap solution and the stub concept I provided after are >> >> >>> more >> >> >>> generic than privacy in either of those proposals. When I say >> >> >>> "object >> >> >>> private state," it’s true that the object in question could be any >> >> >>> object. >> >> >>> But in practice, any realization of the feature would pertain >> >> >>> chiefly >> >> >>> to >> >> >>> class instances, and the examples I gave, though contrived, do >> >> >>> concern >> >> >>> class >> >> >>> instances. The reason private object state is chiefly an issue of >> >> >>> class >> >> >>> instances stems directly from the nature of prototype methods and >> >> >>> accessors, >> >> >>> so if you are not making use of prototypes, you could instead have >> >> >>> used a >> >> >>> closure+factory directly. >> >> >>> >> >> >>> --- >> >> >>> >> >> >>> In a nutshell, my issue with existing proposals could probably be >> >> >>> summarized as a concern that they are neither as generic nor as >> >> >>> simple >> >> >>> as >> >> >>> native slots. To be clear, proper “slots” are an internal concept, >> >> >>> only >> >> >>> observable indirectly — but they are the special sauce underlying a >> >> >>> number >> >> >>> of behaviors which are presently awkward to achieve in ES code >> >> >>> itself, >> >> >>> and >> >> >>> they are a nice simple model of private object state which is >> >> >>> tantalizingly >> >> >>> close to, but not _exactly_ the same as in two critical ways, >> >> >>> symbol >> >> >>> keyed >> >> >>> properties. That said, “real” slots would continue to have an >> >> >>> advantage with >> >> >>> regard to cross-realm stuff even if private symbol keys existed. >> >> >>> >> >> >>> That such a model is radically simpler — minmax and all that — >> >> >>> feels >> >> >>> very >> >> >>> important to me, but I dunno. I’m not holding my breath for big >> >> >>> changes >> >> >>> here. The current stage 3 proposal seems to be unstoppable; much >> >> >>> smarter / >> >> >>> more important people than me have already tried and failed. :) >> >> >>> >> >> >>> >> >> >>> On Sat, Jul 28, 2018 at 3:14 PM Ranando King <king...@gmail.com> >> >> >>> wrote: >> >> >>>> >> >> >>>> In a word... wow. You've got me thinking hard here. Those are some >> >> >>>> peculiar use cases, and they do a great job of highlighting why >> >> >>>> someone >> >> >>>> might forego using `class`. One thing both proposal-class-fields >> >> >>>> and >> >> >>>> proposal-object-members have in common is that the focus is on >> >> >>>> producing >> >> >>>> instance-private fields. All 3 of the scenarios you presented lay >> >> >>>> outside of >> >> >>>> that focus for one reason or another. >> >> >>>> >> >> >>>> > Adding the same “slot” to multiple classes which don’t inherit >> >> >>>> > from >> >> >>>> > each other >> >> >>>> >> >> >>>> I'm a little confused by this one. Are you saying you want >> >> >>>> multiple >> >> >>>> non-hierarchally related classes to have an instance private field >> >> >>>> with >> >> >>>> shared name, such that the same private field name refers to a >> >> >>>> distinct and >> >> >>>> separate field on each instance of every such class, but where any >> >> >>>> such >> >> >>>> instance can have that field referenced by that shared name from >> >> >>>> any >> >> >>>> member >> >> >>>> function of the corresponding classes? (Wow that was wordy to >> >> >>>> write >> >> >>>> out...) >> >> >>>> If this is what you meant, you're describing friend classes. The >> >> >>>> top-down >> >> >>>> processing nature of ES makes this a difficult thing to create a >> >> >>>> clean >> >> >>>> syntax for without risking leaking the private state or >> >> >>>> fundamentally >> >> >>>> altering how ES is processed. Mutual friendship is even harder. >> >> >>>> >> >> >>>> ... and yet I just thought of a way to do it. By telling you this >> >> >>>> I'm >> >> >>>> leaving myself to consider writing a proposal containing 2 new >> >> >>>> keywords: >> >> >>>> `befriend` and `friendly`. I don't know if this can be done with >> >> >>>> the >> >> >>>> existing proposal being what it is. However, with my proposal, >> >> >>>> there's a >> >> >>>> chance. The `friendly` keyword would declare that an object is >> >> >>>> prepared to >> >> >>>> share select information with any object that befriends it. The >> >> >>>> `befriend` >> >> >>>> keyword would allow an object to request friendship with an >> >> >>>> existing >> >> >>>> friendly object. I'm not sure this is a good idea, though. This >> >> >>>> means >> >> >>>> that >> >> >>>> any object declared 'friendly' is automatically insecure as all it >> >> >>>> takes to >> >> >>>> gain access to the selected members of its private space would be >> >> >>>> to >> >> >>>> 'befriend' it. >> >> >>>> >> >> >>>> > Selectively sharing access to private state through functions >> >> >>>> > declared >> >> >>>> > outside the class body >> >> >>>> >> >> >>>> The example you gave above still declares the functions in >> >> >>>> question >> >> >>>> inside the `class` body, so that's not really a solution. If the >> >> >>>> example you >> >> >>>> gave actually solves your use case, then what you're asking for >> >> >>>> here >> >> >>>> isn't >> >> >>>> even needed. If, however, that was a bad example, then it sounds >> >> >>>> like >> >> >>>> you're >> >> >>>> looking for friend functions. See the previous section. >> >> >>>> >> >> >>>> > Adding slots dynamically, e.g. when adding mix-in methods that >> >> >>>> > may >> >> >>>> > initialize a new slot if necessary when called, since >> >> >>>> > subclassing >> >> >>>> > is not >> >> >>>> > always appropriate >> >> >>>> >> >> >>>> Sounds to me like you'd love for `class` syntax to look like this: >> >> >>>> >> >> >>>> ```js >> >> >>>> class [<identifierName1>] [extends <identifierName2>] [mixes >> >> >>>> <identifierName3>[, <identifierName3>[, ...]]] { ... } >> >> >>>> ``` >> >> >>>> so that the private fields of the objects in the `mixes` list are >> >> >>>> added >> >> >>>> to the set of private fields provided by the `class` definition >> >> >>>> directly. >> >> >>>> That would also require another proposal, but I think that can be >> >> >>>> done >> >> >>>> regardless of which instance-private fields proposal gets >> >> >>>> accepted. >> >> >>>> >> >> >>>> On Sat, Jul 28, 2018 at 12:49 PM Darien Valentine >> >> >>>> <valentin...@gmail.com> wrote: >> >> >>>>> >> >> >>>>> To put this another, much briefer way, here’s a hypothetical >> >> >>>>> model >> >> >>>>> for >> >> >>>>> associating private state with objects that would cover me. >> >> >>>>> Privacy >> >> >>>>> would be >> >> >>>>> provided... >> >> >>>>> >> >> >>>>> 1. in the form of symbolic keys whose presence cannot be observed >> >> >>>>> (i.e., they would not be exposed by `getOwnPropertySymbols`) >> >> >>>>> 2. and which have a syntactic declaration so that one can be sure >> >> >>>>> they >> >> >>>>> are really getting private keys (i.e., an api like >> >> >>>>> `Symbol.private()` >> >> >>>>> wouldn’t work) >> >> >>>>> >> >> >>>>> ``` >> >> >>>>> const bar = private(); >> >> >>>>> >> >> >>>>> // alternatively: const #bar; could be anything so long as it’s >> >> >>>>> syntactic >> >> >>>>> >> >> >>>>> class Foo { >> >> >>>>> constructor() { >> >> >>>>> this[bar] = 1; >> >> >>>>> } >> >> >>>>> } >> >> >>>>> >> >> >>>>> // etc >> >> >>>>> ``` >> >> >>>>> >> >> >>>>> The keys would be typeof 'symbol'; the only difference being that >> >> >>>>> they >> >> >>>>> are symbols which are flagged as private when created. They would >> >> >>>>> be >> >> >>>>> permitted only in syntactic property assignments and accesses. >> >> >>>>> Existing >> >> >>>>> reflection utilities would disallow the use or appearance of such >> >> >>>>> symbols >> >> >>>>> both to ensure privacy and to maintain the invariant that they >> >> >>>>> are >> >> >>>>> always >> >> >>>>> simple data properties: >> >> >>>>> >> >> >>>>> ```js >> >> >>>>> Reflect.defineProperty({}, #bar, { ... }); // throws type error >> >> >>>>> Object.getOwnPropertyDescriptors(someObjWithAPrivateSlot); // >> >> >>>>> does >> >> >>>>> not >> >> >>>>> include it >> >> >>>>> foo[bar] = 2; // fine >> >> >>>>> ``` >> >> >>>>> >> >> >>>>> This is significantly simpler than what’s in flight both in terms >> >> >>>>> of >> >> >>>>> syntax and mechanics, which makes me suspicious that I’m probably >> >> >>>>> ignoring >> >> >>>>> things that other people find important. However it would bring >> >> >>>>> parity to ES >> >> >>>>> objects wrt being able to implement genuinely private slots in >> >> >>>>> userland with >> >> >>>>> the same flexibility as what is done internally. >> >> >>>>> >> >> >>>>> In total, this entails a new primary expression, a boolean flag >> >> >>>>> associated with symbol values, and an extra step added to several >> >> >>>>> algorithms >> >> >>>>> associated with Object and Reflect. >> >> >>>>> _______________________________________________ >> >> >>>>> es-discuss mailing list >> >> >>>>> es-discuss@mozilla.org >> >> >>>>> https://mail.mozilla.org/listinfo/es-discuss >> >> > >> >> > >> >> > _______________________________________________ >> >> > es-discuss mailing list >> >> > es-discuss@mozilla.org >> >> > https://mail.mozilla.org/listinfo/es-discuss >> >> > >> >> _______________________________________________ >> >> es-discuss mailing list >> >> es-discuss@mozilla.org >> >> https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss