-
Notifications
You must be signed in to change notification settings - Fork 113
The proposal should be rejected! #148
Comments
Your examples in number 3 would throw; those are different “data” private fields, despite having the same name. If the current spec allows it, it’d be a spec bug that’d need fixing. |
Related: #144 |
It does not. |
@mbrowne The nearest working model that's similar to what happens when declaring |
Thanks @rdking. Did you mean to write that in the other thread, or here? |
NO. spec will allows the bug! a name Next, use If get a privateReference as rhs, will call GetValue() to pick data. now, check binding at 5.b.ii, allow because lex scope has name '#data'; and , get private filed value at 5.b.iv, allows again because the The The BUG is inevitable! Because spec allow "read variable name" operations on private domains! Can not fix it on current sepc! Absolutely! |
@aimingoo, step 5.b.ii of The crucial step is that 5.b.ii resolves |
@mbrowne probably the other thread... oops! |
Oh! Yes, NewPrivateName will return a unique key as name ... god, a map of class and instance's private names!!! I will note in this issue. thanks. |
The fact that when running x.foo = faked.prototype.foo;
x.foo(); // 100? in Chrome throws
means private fields do not give true privacy. Why go through all the hassle of this proposal (which has so much dislike) just to end up having soft privacy instead of the stated goal of hard privacy? It'd be better than this current proposal to make a better syntax, and other changes, without true privacy then. |
It is indeed hard privacy, because you can’t fake it. It’s exactly what would happen if you had a closed-over weakset that stored instances, and threw when the receiver wasn’t in the weakset. |
Is it still considered hard privacy if I can use this trick to detect which private members exist in the class by reading the error message? |
The error message is not specified by the specification. An engine can choose to "leak" the name in the error message, but it can also choose to hide it. |
@trusktr also, any class can wrap the private member access in a try/catch and suppress or fake that error, so that "trick" isn't remotely reliable anyways. |
1. Concept: "Not Fields"!
The Object is defined as "object is collection of properties [^Note 1]" in ECMAScript. So if
Field
is not a property, it must not belong to the concept set of "Object's member (collection elements of object)"; ifFiled
is property, thenpublic field
must be equal toproperty
, there is a conceptual conflict.This is the root of all existing contradictions.
The "proposal-class-fields" proposal is fundamentally contradictory to the core concept of the ECMAScript object. It attempts to illustrate [^Note 2] : an object is a structure defined by a class member, and a class member includes a property name and a private name; The property name defines the property.
In this definition, the object is a "entity of a class member (fields)", and each field define by his name. That is to say, the Object is collection of names, is instance of field definitions by class.
The proposal's stealing of the concept is not only at the narrative level, it is exactly what it is doing. As follows [^Note 3] :
We have clearly seen that the proposal is destruction of the core concepts of Objects. And "Not Fields" is the only way to stop it.
[^Note 1]: "an object is a collection of zero or more properties." ECMAScript Overview part.
[^Note 2]: The FieldDefinition in proposal-class-fields, New Productions part.
[^Note 3]: The DefineField() algorithms in proposal-class-fields, Modified algorithms part.
2. Implementation: Recreated a var!
For next case:
The effect that the proposal attempts to achieve is similar to the following:
Note that the proposal essentially does not "Intended" to provide
private fields
for the object instancethis
, but instead provides a set of names accessible in a particular context through the lexical environment.However, as shown in the example above, if you use this method to provide a private name
data
forthis.foo()
, thenfoo()
will have a lot of Function instances. To prevent a single object from repeatedly binding multiple function instances (as his method), the proposal puts the above "collection of names" as an internal slot in the class, and provide a internal-slot[[PrivateFieldValues]]
as copy (or fork) for this set of names when creating thethis
object.But, there is still some distance from the truth. For this proposal, this is just a stopgap measure to avoid creating separate instances for each object and method. The real situation is that it creates the "PrivateNameScope" for each class, for each function, and for each object, and then maintains the scope in the lexical environment. Since each object "may have" a private domain, in this solution, each function call needs to bear the cost of checking this private domain: every time, every place, and every function-related property.
So the proposal skyrocketed! Most of the internally methods need to add the
PrivateNameScope
parameter to the interface, and each context needs to be added withPrivateNameEnvironment
. [^Note 4]Is it a little familiar? What was the last thing that affected the ECMAScript specification in such a large scope?
That's right, it's VariableEnvironment! It is the
var
declaration that creates a conflict with the "block-level scope", resulting in a historical design with the new syntax keywordlet
enabled. The tricky design ofPrivate Fields
is so obvious that it comes with VariableEnvironment, but it seems that no one of the reviewers sees it:They reinvented the wheel, again. And, it’s square wheel, again.
Two square wheels!
[^Note 4]: Every call in proposal-class-fields, 3.9.9 PrepareForOrdinaryCall.
3.
Obvious: it doesn't work!InefficientNext each function has
privateNameScope
, and so on. So since there are PrivateNameEnvironment or privateNameScope, why should each object have a[[PrivateFieldValues]]
internal slot?The answer is: the internal slot of the object is used to store the field value for the
private name
[^Note 5], and the environment and scope components are used to detect whether theprivate name
can be accessed [^Note 6]!However this is not valid. E.g:But have a problem, E.g:
I have read the complete proposal carefully, yes, the above BUG is inevitable.Because this process is no different:As long as you allow "read variable name" operations on private domains, all privated datas are not safe.
This is a pupil level error, But irreparable, for this proposal.`[^Note 5]: Access field value in proposal-class-fields, 3.5 PrivateFieldGet.
[^Note 6]: Check name binding status in proposal-class-fields, 3.8.1 GetValue.
4 Conclusion
At the abstract level, (in terms of the impact of abstract concepts on users), this proposal destroys or steals the concept of "Object" in ECMAScript; in terms of implementation, it consumes a lot but does not security and cannot achieve
private
expected. I have to say that this is a failed, unusable, rough design, and backward thinking.Recommendation: reject the proposal-class-fields proposal.
The text was updated successfully, but these errors were encountered: