Proposal to fix super and new inconsistency, future-proofing broader uses of new operator
herby at mailbox.sk
Sat Aug 31 03:51:00 PDT 2013
In the present state of the spec, there is little inconsistency between
behaviour of new and super.
What these operation roughly do is:
new Foo(...args) is
super(...args) inside constructor is
This is elegant and consisten solution - super behaves as in any other
method - calling superclass's version of itself.
Since Foo.prototype.constructor is set to Foo by default, no
inconsistency is observed in default case - super(...args) calls the
same function from subclass of Foo and in new Foo.
But if constructor is changed (or deleted / not defined), inconsistency
appears - new still calls Foo, but super calls different function (or
fails if there is no .constuctor in proto chain).
My gut feeling is that new Class and super in SubClass should do the
same thing. Also, if this IMO bug begins to be exploited, to "have
different initialization of own instance versus subclass one", there is
no way back.
There is elegant solution for this by redefining new to do roughly:
new Foo(...args) is
Compared to previous semantics, this is much cleaner and understandable,
and in par with super philosophy of "treat 'constructor' as just another
For default cases, this works identically with the formed definition.
For `class` keyword, if you change constructor method of an existing
class, this semantics nicely implements your intent - to change the way
howe class Foo is initialized (in both new and super).
Remaning scenario is changed .constructor of constructor function.
Here, it can be changed directly (you change .constructor of existing
.prototype) or indirectly (you change .prototype of the constructor
function). Both would break existing web.
The silent assumption of this proposal is, that the former case
(changing .constructor of default .prototype) is rare if it ever
appears, though I did not search for this.
The second case is much more common: one redefines .prototype of a
function, but does not define .constructor there (there was no real
need). I would propose guard against this case - whenever the .prototype
of a function is changed, the new would use old, legacy semantics.
Constructor functions with non-changed .prototypes, as well as `class`es
(which have .prototype non-writable) would work fine with the new,
FUTURE PROOFED BROADER NEW
This change decoupled the need of the Foo in `new Foo` being callable -
so the new semantics of new allows any object having @@create defined to
be usable inside new - the initialization of the instance is nothing
more than just calling 'constructor' method with appropriate args, so
the new instance is responsible for initializing itself, no matter who
was its creator/allocator.
1. It is not known if the case of changing .prototype.constructor
without changing .prototype itself on legacy constructor functions is
really rare or it has its legitimate use and is spread.
2. Instance does not know its creator/class (you cannot do generic 'new
More information about the es-discuss