1. Members marked private being accessible from other instances of the same class [1] is counter to every other OO language I have used. What is the prior art here? Why depart from all conventions like this?
2. The # syntax is not extensible. If TC39 decides to add protected, internal, etc. modifiers in the future, what will they look like? We should be looking to TypeScript's private/protected modifiers as a battle tested solution that fits the existing convention set by the "static" modifier.
---
[1] https://github.com/tc39/proposal-class-fields/issues/15#issu...
C++ works that way, and several other languages do as well. And the use case mentioned in that comment is exactly the reason: the implementation of a class knows how to access both its own private fields and those of another instance of itself, so that it can do comparisons, combinations, or other operations.
If you accept instances of your own class as arguments to a method, you may be templated to think you can access the private fields of those arguments, even if instanceof checks pass, but they may not be there.
1. Afaik every single OO language allows this. I wouldn't know of prior art for the opposite behavior (only allowing access to the same object).
2. TypeScript works under different constraints and - for all intends and purposes - doesn't implement private properties when it comes to the final, running program. The reasons why TypeScript isn't a battle test solution are laid out pretty explicitly in the Github thread.
Ruby and Scala disallow it, to name two (edit: to clarify, Scala supports both modes via private and private[this]). I stand corrected on Java, C#, and C++.
> The reasons why TypeScript isn't a battle test solution are laid out pretty explicitly in the Github thread.
I didn't see that, can you point me to it? Yes, in TS it's a compile-time-only check (as are all TS checks), but what does that have to do with reusing the same keyword for a runtime check?
Almost every statically typed OOP language works this way. In C++, Java, and C#, privacy is class-based, not instance-based.
Privacy is instance-based in Smalltalk and, as I understand it, has been a long-time source of frustration. It makes it very difficult to implement things like an equality method so that an object can compare itself to another of its own type without breaking its own encapsulation.
If you think about it from the perspective of software engineering (and not security, which is generally not what language-level privacy is for), instance-based privacy has no benefits over class-based privacy.
The goal of access control is to encapsulate regions of code from each other so that modification to one doesn't affect others. It establishes fences between different parts of the program to make them less coupled to each other and easier to independently change.
Every instance of the same class shares the exact same code, so there is no point in preventing access between them. It's not like you can encapsulate things such that a change to class A doesn't require a change to... class A. That's the same class that you're already touching.
> We should be looking to TypeScript's private/protected modifiers as a battle tested solution that fits the existing convention set by the "static" modifier.
I believe those rely on static analysis, which JavaScript does not have.
[2] This is addressed here: https://github.com/tc39/proposal-private-fields/blob/master/...
The only instance of something dropped was cancelable observables. AFAIR it was only because some other group at Google opposed it.
Everything else is carried full steam ahead. Enjoy your import() instead of the vastly superior System.loader. Enjoy your hashes as member access specifiers. Dumpster fire. Template literals. BigInts. `new.target`. Dumpster fire. `import.meta`. Dumpster fire