Prototypes as the new class declaration

Irakli Gozalishvili rfobic at gmail.com
Mon Jun 20 03:26:32 PDT 2011




Regards
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/
Address: 29 Rue Saint-Georges, 75009 Paris, France (http://goo.gl/maps/3CHu)


On Saturday, 2011-06-18 at 20:13 , Brendan Eich wrote:

> On Jun 18, 2011, at 8:53 AM, Axel Rauschmayer wrote:
> 
> > > > Where would the prototype of the new instance come from? Would SkinnedMesh.constructor.prototype point to SkinnedMesh?
> > > 
> > > Of course -- Allen's proposal just "rotates" the (constructor, prototype) pair so the named or "outer" object is the prototype.
> > > 
> > > This matches the syntax. It's a bit odd that class syntax has a body that contains constructor, yet the class name binds to that inner constructor function. It works, or we can make it work -- it just seems unusual given the otherwise-pellucid rules for naming objects expressed by braced bodies (initialisers, functions).
> > 
> > 
> > Right, I agree that the appeal of binding the prototype to the class name (instead of the constructor) is that everything makes more sense, especially instanceof and subclassing.
> > 
> > I still don’t understand the “rotates” part, though. The following looks to me like a normal object literal (with the prototype set via the prototype operator). Nothing special about it.
> 
> I was responding to your question "Would SkinnedMesh.constructor.prototype point to SkinnedMesh?"
> 
> In the classes proposal, we have
> 
> 12345678901234567890123456789012345678901234567890123456789012345678901234567890
> [the binding environment] -- 'SkinnedMesh' -+
> . |
> . v
> . [The class object, i.e., the constructor]
> . | ^
> . | |
> . 'prototype' 'constructor'
> . | |
> . v |
> . [The object defined by the class body]
> 
> By "rotate" I meant turn the 2-cycle at the bottom 180 degrees.
> 
> 
> > > const SkinnedMesh = THREE.Mesh <| {
> > > constructor(geometry, materials) {
> > >  super.constructor(geometry, materials);
> > > 
> > >  this.identityMatrix = new THREE.Matrix4();
> > >  this.bones = [];
> > >  this.boneMatrices = [];
> > >  ...
> > > }, 
> > > update(camera) {
> > >  ...
> > >  super.update();
> > > }
> > > }
> > 
> > 
> > Then I would have to make the following assignment:
> > > SkinnedMesh.constructor.prototype = SkinnedMesh;
> 
> 
> You don't need to, in Allen's proposal. But perhaps it was unclear, or even unstated.
> 
> 
> > Now the following works (without a separate protocol):
> > > var sm = new SkinnedMesh.constructor(...);
> 
> Allen's post discussed this.
> 
> 
> > A next step would be the syntactic sugar suggested by Allen:
> > new SkinnedMesh(...) => new SkinnedMesh.constructor(...)
> 
> Yes, and likewise for instanceof -- that all seems fine, although Irakli's gists can't work in JS today assuming such extensions, wherefore his 'new' protocol, which is clever.
> 
> 
> > However: THREE.Mesh would have to refer to the prototype (similarly to how things are done above), for this to work.
> 
> Right. I thought we went over this already here :-).
> 
> The twist with Irakli's gist is that it adds a 'new' method that can work on old-style built-in and user-defined constructor functions, thanks to Object.prototype.new.
> 
> But it is a new (no pun) protocol. It's not separate, though -- it works on old-style constructor functions. You can call x.new for any instance x to get a new instance of the same class or built by the same constructor, provided Object.prototype.new is unshadowed.
> 
> (Irakli, you could pass along arbitrary arguments from Object.prototype.new to new this.constructor, in ES.next using rest and spread, and even in ES5 using the bind trick [http://whereswalden.com/2010/09/07/now-in-spidermonkey-and-firefox-es5s-function-prototype-bind/].)
> 
> So Irakli's work suggests we don't need to extend new and instanceof if we're willing to switch to the new '.new()' protocol.
> 
> But that is a big switch.


I think there's also interesting side effect, I really like, that may not be obvious. With `.new()` protocol `.constructor` becomes obsolete and is kept for "backwards compatibility" only (`new` can be implemented as `return Object.create(this)` instead, which would behave slightly different, but will be closer to what my intent was). Such a direction has a potential of making inheritance very simple and much less confusing for language migrants. Static properties (own properties of constructors) also become unnecessary, as constructors are no longer used, instead overridden method `new` may be used to set up an instance at initialization point.

I believe this is one of the good parts that Crockford has discovered: http://javascript.crockford.com/prototypal.html 

> 
> Extending new and instanceof to probe for .constructor is plausible too, and it avoids breaking the use of these operators on prototype-first "new-style" abstractions.
> 
> /be

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110620/9eb362c4/attachment.html>


More information about the es-discuss mailing list