-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Classes extending a function with .prototype=null #699
Comments
Note that this would be a normative change, but both SpiderMonkey and v8 currently treat |
+1 this looks like a bug to me |
Just curious: what does this mean for the concept of which is the "class"... is it the function (constructor) that's the "class", or is it the prototype object that's the "class"? I think from my experience that most people think of the prototype object as the class, since it's where all the "inherited" functionality derives from. |
@getify: both the constructor and its .prototype play a role (normally, except in the case this issue is pointing out, which is probably a spec bug). This is true in exactly the same way for functions as for classes, whether instantiating or inheriting. |
but my point is, if "superclass" is meant to refer only to the constructor and not the prototype, that muddies the waters... if "class" means both, but we're using only one or the other as the null check, we shouldn't call that specific one, only, a "superclass". |
I'm not sure what uses of those terms you're referring to. In this specific algorithm, |
I need to do some research on the history of this detail, but my first reaction is that this is not necessarily a bug. I have a vague recollection that this use case was on that was discussed at a TC39 meeting, but I'll have to do some research in the meeting notes (and perhaps ES6 drafts or bugs.ecmascript.org) to verify that. Regardless, here is a rationale for the currently specified behavior: Setting the However, here is something that is precluded by the present spec. language: class BareExoticArray extends Array {
//I want to create exotic array objects that don't have any of the Array.prototype methods
construtor () {
super();
}
}
BareExoticArray.prototype = null; According to the spec, Alternative, is we had just left the constructor out of the class definition: class BareExoticArray extends Array {
//I want to create exotic array objects that don't have any of the Array.prototype method
}
BareExoticArray.prototype = null; We would not throw when invoking I'm pretty sure I didn't consider this exotic object subclass use case when write the original spec. for ClassDefinitionEvaluation. So I'm starting to think maybe this is a bug. This is a pretty obscure corner case and the "right" or most desirable behavior is probably debatable. In situations like this the most important thing is consistency of implementations. For such non-intuitive edge cases it is more important that implementations all conform to what the spec. says and less important whether or not the spec. "got it right". I think it is reasonable to treat this as a bug, and try to "get it right". Or not. Most important is getting a spec. and implementations that all match. |
@getify We can meaningfully talk about "classes", "superclasses", and "subclasses" as long as we are referring to syntactic |
@allenwb if the spec says "if superclass is not null" and what it only means is there is a non-null constructor function (regardless of its prototype), that implies the class is just its constructor, since prototype can be empty but we still have a "superclass". I think the most consistent (wrt existing precedent) approaches to this spec wording would be:
|
@allenwb, I don't think new class DerivedBareExoticArray extends BareExoticArray {} would not create an Array exotic object, since I think it is surprising in general to have a class which extends something constructible and then does not call that thing during construction. |
@getify, We could rename it, or have the algorithm check both, in principle (although checking both would be pointless - if an object is null, it does not have a |
@bakkot You're right that the I think the change that would allow the case without the explicit constructor to allow work is to change step 15 to:
Note that I'm intentionally using superclass there and not constructorParent. |
@allenwb, I think your example works without an explicit constructor as well, because in your example To make my |
yes, need to also use superclass in 10a. This is actually a bit hooky in that superclass was originally intended to be local to the step 6 else clause. It doesn't have a defined value if step 6 isn't evaluated. The "classHeritage is present" predicates should be an adequate guard to prevent that from being a problem. Perhaps, this should be cleaned up but need to be careful to maintain the distinction between superclass and constructorParent. |
Currently (see ClassDefinitionEvaluation 6.g.i, 10.a, and 15), class
B
below is considered to be a base class.From what I can tell, this means that
A
will never be invoked - i.e., this is identical toclass B extends null {}
, except that the[[Prototype]]
ofB
will beA
. This seems wrong. I believe instead that 10.a and 15 should read "if superclass is not null" instead of referring to "protoParent".The text was updated successfully, but these errors were encountered: