Destructuring instances with private fields
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:
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.
BTW, this just falls out of the grid with my private symbols suggestion.... tc39/proposal-class-fields#115
I can make it work work under my proposal-object-members by making '#' a postfix unary operator, but then it would have to be a syntax error to use it that way unless we're dealing with a destructuring operation. That just opens up too many ways to abuse it and leak the private container. So that's a no-go as well.
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.
:class Foo { bar = 1; method() { const { bar } = this; /* … */ } }
The same approach would currently be illegal syntax if
bar
is declared to be private: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:
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] tc39/proposal-class-fields#4