Open drpicox opened 7 years ago
I believe JavaScript classes are already used so broadly that we can't go back and change its semantics. There is very broad use of public own properties in the JavaScript language.
I think that you have not understood my proposal. Please, give me few days that I will write a simple wrapper in plain Javascript (no babel required) that would do the same job:
const Animal = strict(class {…});
Ops. It does not. I need precompile to know when I am exporting this outside the functions and when I have a complex input with other thisses of the same class.
addItself(list) {
if (!list.includes(this)) {
list.push(this);
}
}
@littledan this proposal doesn't affect any existing code, I think you overlooked the strict
keyword (please correct me if you did and have an argument to counter).
I think the same @rwaldron but probably @littledan has a more broad view of privates and lot of hard work about its implications.
In fact I found a kind of implementation of my last example here: https://www.npmjs.com/package/private-class
Sorry, I did miss the strict
keyword. Previously, an idea has been proposed of const
classes--this seems related. Syntactically, it seems like it should work just fine--async
isn't a keyword either, but if you put it in the right places it can act like one.
Do strict classes as proposed here need to be part of the private fields proposal, or could they proceed as a separate proposal?
The idea is close to the approach of ES5 of "strict": it changed the behaviour of Javascript but just in functions or files.
For example, imagine that we can do something like:
This example would be translated in exactly the same presented in the introduction. Note that functions, getters and setters are present in the prototype, so they are public, but values for x and y are in this, so they would be private.
Considering something like:
Using this would be something like:
Something remaining to decide is what to do if there is an assignation:
I bet for B, because is more in the line of the philosophy of this solution. If you want to add metadata, please use a WeakMap or similar approach.
Philosophy of the solution
The idea is that private variables are great for encapsulation. Closures are also great, but you cannot access to other instances privates. That is the reason why privates are great.
Usually it is considered bad practice to expose class internal representation. Make some properties private and some properties public drives to bad practices. Making all private but prototype properties effectively promote good practices.
You can expose some internal state through getters and setters (they are defined in the prototype). It ensures that you can effectively control manipulations to your class internal state.
It is not bad to force all properties to be private, you can always use legacy classes and legacy objects. So you can get rid of private limitations, if you need (for example because of performance), just using legacy classes.
It keeps Javascript very similar to the one that we know. Even better, we can port code to the new implementation as easily as adding the
strict
keyword in front of the class definition. Betting for the option B we should also be able to catch easily legacy parts accessing to the internal state.Addendum
I am aware that
strict
is not a keyword, but I love it. It fits very well: we are limiting what we are able to do like it happened before in ES5.But we have other keywords suitable, like
public
. It might be funny to seepublic class Point { ... }
.I also have designed it all taking into account most work done with the current specification, so it could be reused. Semantics should be very similar. It is close to replacing all
this.that
bythis.#that
, except for the ones that are in the prototype (which require a fallback for the prototype) and option B that would be ideal for this proposal (note that option A is the current).Other considerations
You can also define private functions:
or: