Normative: Make PrivateName a defensible class #134
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This patch makes PrivateName a deeply frozen, "defensible" class,
whereas in previous iterations, it was represented as a primitive, an
ordinary class, and finally an object with own methods and a null
prototype.
The goal of using a defensible class by default, as opposed to being
an ordinary class that users can freeze, is to protect privacy by
deafult against complex scenarios. In modern JavaScript code, a
decorator which others depend on may be implemented in a deep
dependency and unable to capture/freeze the original value of
PrivateName.prototype proerties. As a result, monkey-patching of that
object can make it difficult to preserve privacy of decorated private
class elements. A defensible-by-default PrivateName achieves the goal.
See [1] for past discussion.
The details of the PrivateName class are as follows, based on advice
[2] from Mark Miller:
decision [3] to not expose the PrivateName constructor.
If we were to support new-ing the PrivateName constructor, the semantics
would be such that instance is frozen only if new.target === PrivateName.
[1] #68
[2] #129 (comment)
[3] #68 (comment)