First, about accessing private fields on members of the same class: the spec will allow this via `other.#foo`.
The reason I said that the difference between `object.foo` and `object.#foo` is not purely syntax is because they are two completely different actions. The first is a lookup in the object's property map/prototype chain. The second is a private field lookup.
`object.foo`:
1. Check to see if there's a property named "foo" in `object`'s property map.
1a. If yes, return the value.
1b. If no, continue.
2. Does this object have a prototype?
2a. If no, return undefined.
2b. If yes, repeat these steps starting from 1 using this object's prototype.
`object.#foo`:
1. Test to see if you're in a class.
1a. If no, throw a Syntax Error.
1b. If yes, continue.
2. Test to see if `object` is an instance of this class.
2a. If no, throw a Syntax Error.
2b. If yes, continue.
3. Test to see if the class defines a private field *#foo*.
3a. If no, throw a Syntax Error ? (Not positive on this one, it might just return undefined).
3b. If yes, continue.
4. Look up this class' private fields for `object`.
5. Get the value for *#foo*.
In case it wasn't clear: the private field `object.#foo` is NOT a property on `object` named `foo` and marked private. It is a field which exists in a namespace only accessible to the class definition. Without the
# sigil, there'd be two issues. See [0] for a pseudo example of how private fields really behave.
The first issue comes from a decision made in the spec by the committee: private fields must not interfere with object properties. This essentially means that an object can have the private field #foo AND the object property "foo" (as I described here [1]). Without the #, the fields would have to exist in the same namespace as the object's properties. If you error out when `object.foo` is accessed outside of the class definition, it would not fit the spec's definition of "private". [2] [3]
The second issue is that without the #, the compiler would need to determine at the call site which lookup method to use, and they decided this would incur too much overhead on every single lookup in the already complicated property lookup logic.
0: https://news.ycombinator.com/item?id=18707421
1: https://news.ycombinator.com/item?id=18706363
2: https://github.com/tc39/proposal-class-fields/blob/master/PR...
3: https://github.com/tc39/proposal-class-fields/blob/master/PR...