Yes, your comment is the actual issue. See my earlier comment:
If I'm understanding things right, TC39 members are thinking that...
... and you think this is a problem
... if the static and instance contexts were allowed to declare a private of the same name.
There's just one problem with that line of thought. It all hinges on the choices that were made about how to access the private fields. I can easily show you an approach that would not suffer from such an issue.
Given foo.#x
:
1. Assert(foo is an Object)
2. Let C = (current execution context)[[class]]
3. Assert(C)
4. Assert (C in foo[[classes]])
5. Let N = C.privateNames
6. Assert("x" in N);
7. return foo[N.get("x")]
Under the presumption that foo[[classes]]
is the list of constructor functions that initiated foo, and (current execution context)[[class]]
is the class in which the currently executing function was declared, then there would be no worries about which field is being looked up since the name lookup would be checked against an internal list pointing to the classes whose private members are accessible.
When a class instance is being created, each constructor initializing the object would add itself to that instance's [[classes]]. As for new classes, the static constructor would add the class itself to its [[classes]]. It's really not that hard. It's just that a less effective approach was taken. The one I just described would allow private to work just like public, but without the public access. It would also allow for some form of a controlled "shared private" (also known as protected).
The point is that it isn't a limitation in the semantics of private, but just how TC39 decided it should be implemented.
Anything can be given instance slots, including the constructor that already had the same-named field, using the return override trick - so if that were allowed, it would always be possible for something to have both a static and instance field with the same name. Thus, itβs not allowed.
You can run an instance through the override trick to try an install a private field twice and you'll get an error. I don't think anyone would be upset if that continued to be the case for the constructor given a static field of the same private name.
It should always be the case that a "friendly name" collision will cause an error. That's a per-object issue. That's something everyone would expect. What's unexpected is that the same friendly name cannot reference 2 different private fields on 2 different objects. I think it just a bit disingenuous to use an argument about a single object to decry an issue about 2 separate objects.
The class constructor is very much a different object from instances of that class. Using the return override trick, and acknowledging it as a "trick", makes for a poor reason to avoid behavior that is logically consistent with what developers can, should, and do reasonably expect.