Allen Wirfs-Brock wrote:
OK, I ready you proposal. I'll summaries it:
class Sub extends Super {
constructor (...args) {
super(...args); //or super.constructor(...args) because they mean the
same thing.
}
}
creates an (almost) ordinary object that is the initial value of the Sub binding. The
[[Prototype]] of Sub is the value of Super. Sub is created with a "prototype" property
whose value is a new ordinary object whose [[Prototype]] values is Super.prototype. Sub.prototype
has a method property named "constructor" whose value is a super bound method function
with the user specified body. There is nothing special about this method, it it just like any
other method defined in a class declaration. In particular it does not have a [[Construct]]
internal property.
The only thing exotic about Sub is that the object has a [[Construct]] internal
method. It does not have a [[Call]] internal method. The definition of its
[[Construct]] in almost JS pseudo code is:
//internal method this.[[Constructor]](argList):
let newObj = this.@@create(); //eg Sub.@@create();
let replacementObj = this.prototype.constructor.apply(newObj, argList);
if (typeof replacementObj == "object"&& replacementObj !== null) return
replacementObj
return newObj;
Implications:
Sub === Sub.prototype.constructor evaluates to false.
To create a new instance of Sub say:
new Sub()
The following is a TypeError, because Sub does not have a [[Call]] internal
method:
Sub()
The following is a TypeError, because Sub.prototype.constructor does not
have a [[Construct]] internal method:
new Sub.prototype.constructor()
Sub.prototype.constructor can be called directly or as a method invocation
including via a super call a subclass of Sub.
It seems to me, all you have accomplished here is to make it illegal
to call a class object directly as a function. If we were starting
From technical PoV*, yes.
Oh, and I fixed the super / new inconsistency.
over that might be a reasonable design choice. But we have a legacy
to consider. Even if we think we should discourage direct calls to
Ignoring Foo.call(this) replacable by super, mostly, "class" is used for
new Foo and for Foo.staticVar. I argued the change is big in its wider
implication, even scary, maybe (but I see it as in fact minimal), but
should not (imo) beat legacy much; because the fact of the tight
coupling was not exploited so much.
class objects (I think I'm now in that camp) actually making it an
error seems like it may be too big of a step away from the legacy
conventions.
And there is no better time to do that step than now, when class is new
construct in the language.
*There is more than narrow technical PoV. By returning plain object
with exotic [[Construct]], working in nearly every detail as a class,
while affording not to be the constructor itself, you effective say
openly "You can use any [[Construct]]ified object as a class in ES6+.
Gates are finally open".
It can be blessed by Reflect.makeClass(classObject, protoObject) or
similar API.
It can bring lots of new patterns and cowpaths into the language.
If people don't want plain object to be the class, but their existing
object x, they do
Reflect.makeClass(x, (class {...}).prototype);
and they then can `new x`. They choose what they will use as x for new
operator; because now class is one object and constructor is another.
For example, the criticized pattern of 'function that does differently
for [[Call]] and [[Construct]]' could now be created as well. Just
'makeClass' it.
The main message of this proposal is that beyond fixing super/new
inconsistency, it opens new world for "classes", not restricted by the
legacy tightly bound class===constructor objects.
And by making class to return this kind of 'decoupled' classes, this
widened view to "who may be used as a class in new / extends?" is
effectively blessed.
You cannot open it later. Because there will be lagacy code that already
uses `class`.
(I'd stress again, that, imo, that change is very little, too little for
the fruits it can bear. Fix me if it breaks something critical)
Allen
Herby
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss