-
Notifications
You must be signed in to change notification settings - Fork 113
Remove the private fields idea ("#"), at least for now #73
Comments
There’s many kinds of decorators, so the “i typed the wrong thing” hazard would apply to that too. There’s never a substitute for manual or automated testing (and linting), so if you mis-type a #, you’d discover it when running your code, just like many other bugs. |
"you’d discover it when running your code" is not a good rationale for allowing a surface area for a bug. With the decorator idea, all you need to do is remove the decorator to publicize a private variable. With "#", you need to change every occurrence, which could be dozens or even more. So the hazard is much wider. Access control doesn't have value at run time. It's a way to simplify and filter auto complete while accessing an instance's fields and methods from outside the class. |
We’re not optimizing for converting from private to public - imo that’s a very rare operation. It’ll be far more common to convert from public to private. Access control has tons of value at runtime - it’s got literally nothing to do with autocomplete and 100% to do with preventing any observation of private state. |
I've never used "private" for anything other than cleaning up my class's public interface for external consumption, so in my experience, everything to do with autocomplete. What is the value in "preventing any observation of private state"? Can you give an example? (please don't point me to articles, I want an example that clarifies your assertion) |
https://github.com/tc39/proposal-class-fields/blob/master/PRIVATE_SYNTAX_FAQ.md#what-do-you-mean-by-encapsulation--hard-private explains the requirement rather well. What someone is used to doing in most other languages is irrelevant, because most other languages have a broken concept of “private” in that you can always reflect and observe that private state. In JS, private will truly mean “private”. |
Here's a specific example. I also want to say that private state is also typically a mechanism for avoiding name collisions, which a decorator wouldn't help with. |
Has this ever been proven? Those who want to expose internal code will just edit the source code. It is conjecture therefore to presume about what this would solve, since there isn't a language case that does the same, as far as I know. The downside also hasn't been examined: people drill into undocumented code for a reason: it allows functionality that is not otherwise possible/offered. So the rationale for this entire feature therefore seems incredibly one-sided, besides conjecture about whether it'll achieve its "goal", leaving aside who prefers it or not. |
If you don’t want it, you don’t need to use it. You can already use symbols or naming conventions to make something quasi-private, if you truly don’t care if people mess with it. For those who do care, it’s currently impossible in a practical sense, and this proposal makes it ergonomic. |
The more general reflection vs encapsulation debate has been had at great length already, both on Github and in committee, and I don't think we want to revisit it yet again. We have examined the tradeoffs involved, including the freedom to tinker and to add functionality not otherwise possible. (Incidentally, other languages do have similar facilities - for example, Java 9 introduced modules in large part because the language's existing "private" wasn't good enough, and they needed strong encapsulation in exactly the sense offered by this proposal. And closures have offered very much the same sort of privacy in JavaScript for a long, long time; they were just less practical to use with classes.) |
I'm guessing there's no way of having "hard private" and allowing a one-step refactoring to convert from public to private and vice versa. @ljharb I think you probably meant to say that converting from private to public (at least read-only) is more common, because e.g. a library that converts a public property to private would be a breaking change. |
I'd expect tooling to be more than up to the task of refactoring between public and private in a single step. There's no way to do it by changing just the definition site, though, no. |
If that really is the case, then I'd have to say I'm satisfied with the proposal as-is, despite the downsides:
The upside (accepted) "Hard private" has its value in libraries where consumer code is unseen, and allows "internals" to be changed freely without fear of breaking anyone's code. Given the balance of these pros and cons, I am closing this issue, until I become aware of any way to avoid downside number 1 while preserving "hard private". |
This is so ugly. Can there be something other than the '#' character? Why not just a keyword class {
whatever x = 5
} Where "whatever" is a clean word that anyone reading would understand and is also not painful to the eyes of time. |
@babakness "ugly" is subjective; if you'd read the FAQ you'll see why no keyword is feasible. |
OK but its such an edge case to make something really private than to just hide it from auto-complete that giving up "#" is throwing away a symbol with lots of potential in the future. Why not, '###' if it has to be '#' |
It’s not an edge case. It’s one of the primary goals of the feature. |
I often publicise private variables and privatise public variables (when developing in other languages). The "#" scheme increases the effort to do so and increases the chances of bugs being introduced in doing so (by failing to remove/add the "#" in one or more cases).
If this.x and this.#x are both allowed, then obviously changing the access status of one would cause a clash. I don't accept therefore that allowing this would be desirable let alone necessary.
An alternative is to allow access control at development time only, where all the value of access control really exists anyway, via e.g. a decorator like @Private. This solves all requirements. But I don't see the value of having private fields implementation at run time anyway. Who does it help, and in what cases? As a developer utilizing private fields I don't need any run time error that says "that field is private". I need a development time "error"/filter that simplifies the interface of a class to public properties and methods only.
The text was updated successfully, but these errors were encountered: