-
Notifications
You must be signed in to change notification settings - Fork 57
Subclassing BigInt question #98
Comments
I have no idea what anyone would want to subclass primitives for, but it's important that we make the semantics well-defined here. If someone knows what they're doing, they can subclass BigInt and make a constructor that doesn't throw in the sort of ES5 subclassing way: class B extends BigInt {
constructor(value) {
let self = Object(BigInt(value));
Object.setPrototypeOf(self, B.prototype);
// do whatever else with self
return self;
}
} I agree with you that both of the pieces of code you wrote should throw a TypeError. Symbol seems to have the same behavior with subclassing as you describe. I don't know if this was identified as a downside in the development of ES6, but this was a model I was trying to follow in the BigInt specification. Anyone else know the history here? cc @allenwb @rossberg |
That's interesting. I'm asking that because og |
@caiolima I don't understand your question. When would that test go through The subclassing trick I'm using here creates a BigInt wrapper by calling |
Ooh, My question is about thisBigIntValue Abstract operation: The abstract operation thisBigIntValue(value) performs the following steps:
If I apply this operation to a instance of B, should it throw an exception or return the BigInt? |
It should return the BigInt. The object will have a [[BigIntData]] internal slot because it is a regular old BigInt wrapper instance, whose prototype has then been changed. |
O think I'm done with the question then. Closing the issue for now. |
Generally, I would expect any new primitive wrapper "class" to follow the pattern established by, early ES in that you can use However, in defining ES6, we decide to deviate from that pattern because of one symbol-specific anti-use case. The conceptual model of Symbols is that each primitive symbol value in a program has to be explicitly created. This model is somewhat different from the legacy primitive types whose values have a more declarative existential nature. You newer need to instantiate a primitive number value, it is expressed as a literal or is produced as a result of a computation. But symbols have to be explicitly created and TC39 chose to make let sym1 = new Symbol("supersecret"); //I think I'm creating a secret symbol property key
let objWithSecret = {
[sym1]: "this is a big secret"
}; Because, of the Symbol toString method. The actual property name used for the property defined for objWithSecret would be the string value The decision to break the legacy wrapper pattern by now allowing I don't see any similar problems with BigInt. Hopefully, devs will think of them similarly to other (non-Ssymbol) primitive types, especially like Number. For that reason, I would suggest consistently following the constructor pattern used by all of the legacy wrapper classes and not follow the special case of Symbol. |
See #13 for previous discussion of this question. Another point was to just generally discourage people from doing |
I'm not sure if it is possible to subclass BigInt. If I'm no wrong, based on BigInt constructor, we should throw TypeErrror if newTarget is not undefined. So, if we have:
In both cases the correct result is throw type error, right?
The text was updated successfully, but these errors were encountered: