Destructuring instances with private fields

Ranando King kingmph at gmail.com
Thu Sep 6 14:13:34 UTC 2018


I can understand why this would be wanted. It would save some excess
typing. However, doesn't it also lead to the potential foot-gun of
forgetting to assign any modifications back to the original private field?
Also, since private fields aren't actually own properties of the instance,
how could they possibly be destructured? There's no programmatically
exposed listing of the private fields. Further, under proposal-class-fields
private fields are restricted to just `class` instances, so the
destructuring syntax doesn't make sense for that scenario. Basically it
would imply that the following is true:

```js
let bar1 = "bar", bar2;
({ #fubar: bar2}) = { #fubar: bar1 };
bar1 === bar2;
```

Even if proposal-class-fields allowed for private fields on objects, it
wouldn't work. There's no way to reify the left side's `#fubar` as a
private name of the object on the right side before processing the object
on the right side. Put another way, without `obj.` in front of it, `#field`
cannot be lexically resolved as a private name while parsing unless the
parser, upon finding the object on the right side of the `=`, re-evaluates
the left side. Since destructuring can be arbitrarily complex, this becomes
a mess very nearly as complex as trying to accurately deep clone an
arbitrary object.

On Wed, Sep 5, 2018 at 3:12 PM kdex <kdex at kdex.de> wrote:

> Often times, when I use a class field a lot, I create a local binding for
> it,
> so that I don't have to prefix every appearance with `this.`:
>
> ```js
> class Foo {
>         bar = 1;
>         method() {
>                 const { bar } = this;
>                 /* … */
>         }
> }
> ```
>
> The same approach would currently be illegal syntax if `bar` is declared
> to be
> private:
>
> ```js
> class Foo {
>         #bar = 1;
>         method() {
>                 const { #bar } = this;
>                 /* … */
>         }
> }
> ```
>
> How is the destructuring assignment supposed to behave anyway? Introduce a
> local `bar` binding, just like above?
>
> Whatever it should do, even defining an explicit name for the binding is
> currently illegal:
>
> ```js
> class Foo {
>         #bar = 1;
>         method() {
>                 const { #bar: bar } = this;
>                 /* … */
>         }
> }
> ```
>
> This feels really asymmetric to public fields and has come up in the class
> fields proposal[1] before, though it was suggested to defer it to a
> separate
> proposal.
>
> Is someone currently working on said proposal?
>
> [1] https://github.com/tc39/proposal-class-fields/issues/4
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20180906/5c5e8134/attachment.html>


More information about the es-discuss mailing list