On Jul 7, 2012, at 8:14 PM, Luke Hoban wrote:
> Two questions on maximally minimal classes.
>> 1) Should a super constructor call be made if no derived constructor is specified?
>> The wiki and spec drafts suggest that no super call is made automatically on behalf of the developer if they leave off a constructor declaration in a derived class. So the example below would run without error and print 'undefined'.
>> class Animal { constructor(name) { this.name = name; } }
> class Snake extends Animal { }
> var sam = new Snake("Sammy the Python")
> console.log(sam.name)
>> This looks likely to cause problems in practice. Would it be better to behave similar to Ruby/CoffeeScript where the default constructor of a class with a super class specified is to apply the super constructor with the same arguments? So the above would print 'Sammy the Python'.
so would:
class Example extends Object {};
var x = new Example();
call the Object constructor (as a function) with no argument. That is going to allocate an extra object that gets immediately discarded but I guess that is harmless. However, it's not clear to me why
class Example2 {}
shouldn't also make that pointless call, if we do it in the first case.
Also not that Object.prototype.constructor is a writable property. That means that somebody could hijack such automatic calls to and take control of the initialization of all such objects.
I see where you are coming from on this, however to some degree the logic in support of it it feels awfully close to the logic for providing auto coercions (which we have, but most people regret).
Not everybody seems to agree that what Ruby does is desirable. See the comments on http://odetocode.com/Blogs/scott/archive/2010/07/13/ruby-initialize-and-super.aspx
>> 2) Should explicit constructors without any calls to super be an error in classes with declared super classes?
I feel much stronger that this should be a no. Maybe the whole point of the subclass is eliminate something undesirable in the super class constructor. This is a dynamic language, many things are possible. Let's not over constrain the developer.
Also, if it wasn't clear from above, I'm not a big fan of
class Example2 {}
having different semantics from
class Example2 extends Object {}
(although if you read the ES6 draft carefully you will see that
class Example2 {}
is actually specified to be equivalent to
class Example2 extends Object.prototype {}
this ensures that the Example2 class object does not inherit Object class methods such as Object.defineProperty. If you want to inherit those methods you would implicitly say
class Example2 extends Object {};
)
>> Similar to the first issue above - the wiki and spec draft say that the following runs without error and prints 'undefined'.
>> class Animal { constructor() { this.data = "hello"; } }
> class Snake extends Animal { constructor() { } }
> var sam = new Snake()
> console.log(sam.data)
>> Again, it looks easy to accidentally miss making a super constructor call from an explicit derived class constructor. There's less that can be usefully done about this case than in #1 above. But this might be a case where a stronger static check is warranted. Something like: report an early error when a constructor in a class with a super class specified does not include any super call. This may have to be left to lint tools though.
I think lint tools would be a fine place for this sort of audit rule.
allen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120709/736caec7/attachment.html>