new instantiation design alternatives

Andrea Giammarchi andrea.giammarchi at gmail.com
Fri Sep 19 05:09:21 PDT 2014


I wish it was ... and it looks like migration it's possible with some (a
lot!) overhead ... here a stupid ES5ish example on how we could subclass an
Array (missing all methods that should return new MyArray instead of Array
such slice, splice, concat, etc...)

```js
function MyArray() {
  'use strict'; // new MyArray or die

  // as ES5 compatible alias for `this`
  // since `this = ...` would throw otherwise
  var self = this;

  // whenever it's needed, if needed
  self = duper.apply(self, arguments);

  // overwrite the returned instance in all cases
  // or in all cases duper.apply was not needed
  return self === this ? duper.call(this) : self;

}

MyArray.prototype = Object.create(
  Array.prototype,
  {constructor:{value: MyArray }}
  // other methods and stuff ...
);

var ma = new MyArray(1, 2, 3);

[
  ma instanceof MyArray,
  ma instanceof Array,
  ma,
  test.apply(null, ma),
  {}.toString.call(ma)
].join('\n');

// just to test if it works OK
function test() {
  return [].slice.call(arguments);
}

/*
true
true
1,2,3
1,2,3
[object Array]
*/
```

The used `duper` function is a temporary abomination such:

```js
function duper() {
  var
    proto = Object.getPrototypeOf(this),
    descriptors = Object.getOwnPropertyDescriptors(this),
    // might fail, just as example for Array subclassing
    self = Object.getPrototypeOf(proto)
             .constructor.apply(this, arguments)
  ;
  return Object.defineProperties(
    Object.setPrototypeOf(self, proto),
    descriptors
  );
}
```
That should be aware of both exotic and built-ins and behave accordingly
(e.g. HTMLDivElement would result in `document.createElement('div')`
instead) while [getOwnPropertyDescriptors](
https://gist.github.com/WebReflection/9317065) has been previously
discussed already.

This does not look great, good, or probably even reasonable, but it's
somehow "shimmable" which is honestly my only major concern about
subclassing built-ins and exotic objects.

My .02

Best Regards



On Fri, Sep 19, 2014 at 12:25 PM, Kevin Smith <zenparsing at gmail.com> wrote:

>
>> I'm not sure that having two different ways to do subclassing is good.
>>
>
> Follow me down the rabbit hole...
>
> I think we all want a unified model of class inheritance.  In ES5, the
> model is unified, but only because the built-ins are not truly subclassable.
>
> The ES5 model looks like this:
>
> - Every object starts off with the same undifferentiated shape.  I'm
> imagining a circle.
> - The constructor is passed the newborn object and is tasked with
> differentiating it in whatever manner it sees fit.
>
> Let's call this **Model A**.
>
> This model works really well.  It's simple, flexible, dynamic, and
> composable.  Subclassing works via prototype chains and the composability
> of constructors.  Ignoring @@create, the current ES6 draft does a beautiful
> job of capturing and optimizing this model.
>
> However, it falls short when we try to subclass built-ins and exotics:
>
> - Built-ins and exotics start life with a different and fully
> differentiated state.  I'm imagining squares, stars, triangles, and
> octagons.
> - The constructors of built-ins and exotics are not composable.  Instead
> of differentiating objects, they birth objects.
>
> Let's call this **Model B**.
>
> The design introduced by this thread ("this=new super") effectively
> changes the inheritance model to match Model B, while supporting Model A as
> a legacy feature.  In my opinion, this is a mistake.  It sacrifices the
> common case of classes rooted on regular objects to the edge case of
> classes rooted on built-ins and exotics.  It makes the ES inheritance model
> more fussy and less functional.
>
> In my opinion, constructors conforming to Model B should be considered
> legacy cruft.  Model A should be the unified inheritance model going
> forward, and new built-ins and exotics should be written to conform to
> Model A, or should be future-friendly with Model A.
>
> The class initializer syntax shouldn't be viewed as purely a means of
> parent class initialization.  It a general-purpose facility for providing a
> "this" value to a constructor when invoked via `new`.  It can be used for
> many novel features, one of which is supporting legacy Model B parent
> classes.
>
> So, is this "Model A" centered vision plausible?
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140919/b894bd32/attachment-0001.html>


More information about the es-discuss mailing list