I've been thinking about the problems around this some more. At first I
couldn't get past the dissenting arguments from issue #123, but I've since
come up with a solution that might work. What if:
* Make it illegal to define a class directly on a class field in a class
declaration.
* Move the assignment portion of a class field declaration into a getter on
the prototype such that the getter sets an own property on the instance if
it doesn't exist, then returns that value
What I mean is this:
```js
class Example {
//classField = class{}; //Error
otherField=[ "foo", "bar"];
}
class ES6Example {
//classField ignored for this example since it was an error.
get otherField() {
if ((this instanceof ES6Example) && !this.hasOwnProperty("otherField"))
this.otherField = [ "foo", "bar" ];
return this.otherField;
}
}
```
Done this way, any code expecting early assignment of a field being used as
though it were "abstract" will still work as expected.
On Thu, Aug 30, 2018 at 4:38 PM doodad-js Admin <[email protected]> wrote:
> I'm late to the party, but I've found a solution for my non-loved
> framework : have another constructor called before "super", which fills a
> faked "this" and a faked "args" then replicated values to "this" after
> doing "super(...fakedArgs)".
>
>
> https://github.com/doodadjs/doodad-js/blob/v9.1.3/src/common/Bootstrap.js#L5320-L5330
>
> -----Original Message-----
> From: Isiah Meadows <[email protected]>
> Sent: Sunday, August 26, 2018 3:29 PM
> To: Logan Smyth <[email protected]>
> Cc: Ben Wiley <[email protected]>; es-discuss <
> [email protected]>
> Subject: Re: constructor, super, and data members issue
>
> Yeah, I was more focused on the static class side of things, because I
> thought they were referring to that. Class instance fields are different,
> and so of course, those are never set on the prototype unless for whatever
> reason, the parent constructor returns `Object.getPrototypeOf(this)`
> instead of letting it default to the normal `this`.
>
> My bad, and you are correct.
>
> -----
>
> Isiah Meadows
> [email protected]
> www.isiahmeadows.com
>
> On Sun, Aug 26, 2018 at 12:20 PM Logan Smyth <[email protected]>
> wrote:
> >
> > Static class fields run their initializers and define the properties
> > at declaration time, and class constructors have the parent class as
> > the `[[Prototype]]`, so static field values are inherited. I think this
> is adding to confusion though, because while that's absolutely true, that
> is not applicable in the same way to non-static class fields, which is what
> this original email is focused on. You could indeed also address this with
> static properties in a proper ES6 environment as ``` class Base {
> > static idAttribute = "id";
> >
> > constructor() {
> > this.idAttribute = new.target.idAttribute;
> > }
> > }
> > class Derived extends Base {
> > static idAttribute = "_id";
> >
> > constructor() {
> > super();
> > }
> > }
> > ```
> >
> > On Sun, Aug 26, 2018 at 10:35 AM Isiah Meadows <[email protected]>
> wrote:
> >>
> >> Every object, including functions, have an internal prototype.
> Functions normally have one set to `Function.prototype`, and objects
> normally inherit from `Object.prototype` at least indirectly. But because
> of how prototypes work, the only requirement for something to be used as a
> prototype is that it must be an object. So you can do
> `Object.create(someFunction)` and although you can't call it (it's not a
> callable object), that object inherits all the properties and methods from
> that function. `class` in JavaScript is just sugar over a common pattern
> (really complex sugar requiring `new.target` to emulate, but still sugar),
> not an entirely new concept, and it all builds off of prototypes.
> Specifically, the instance prototype inherits from the parent prototype,
> and the class constructor itself inherits from the parent constructor.
> That's why if you declare a static `call` method on a parent class, you can
> still access and use it in the subclass.
> >> On Sat, Aug 25, 2018 at 19:58 Ben Wiley <[email protected]>
> wrote:
> >>>
> >>> How can they be prototypically inherited if they don't live on the
> prototype? I feel like I'm missing something.
> >>>
> >>> Le sam. 25 août 2018 19 h 53, Isiah Meadows <[email protected]>
> a écrit :
> >>>>
> >>>> Class fields are prototypically inherited just like via `Object
> create`. This is more useful than you might think, and it's the main reason
> anyone actually cares about static fields beyond namespacing.
> >>>> On Sat, Aug 25, 2018 at 14:36 Ben Wiley <[email protected]>
> wrote:
> >>>>>
> >>>>> All this just reminds me of *my opinion* that class fields is a
> borrowed concept from statically typed languages that is misplaced in a
> dynamically typed languages like JavaScript.
> >>>>>
> >>>>> In C++ I use class fields to declare what properties will be
> allocated and instantiated when a new class member is constructed.
> >>>>>
> >>>>> In the ES proposal for class fields we mimic this type of behavior
> by instantiating properties on the object when it's constructed, but
> there's no runtime guarantee that this set of properties will remain the
> same.
> >>>>>
> >>>>> There's no reason not to put this in the constructor, and although
> putting class fields on the prototype is debatably not the best idea, it
> would be the only scenario where we get some kind of new helpful behavior
> out of it.
> >>>>>
> >>>>> Ben
> >>>>>
> >>>>> Le sam. 25 août 2018 14 h 25, Augusto Moura <
> [email protected]> a écrit :
> >>>>>>
> >>>>>> 24-08-2018 19:29, Aaron Gray <[email protected]>:
> >>>>>>
> >>>>>> >
> >>>>>> > Yeah it does look like its badly "broken by design".
> >>>>>> >
> >>>>>>
> >>>>>> Why this behaviour is broken? Every OOP language that I worked
> >>>>>> with behaves de same way, and there's not many developers
> >>>>>> complaining about it. If you want to use a property that might be
> >>>>>> overrided in a subclasss you need to use a method and make the
> >>>>>> source of the data more versatile (in Java and others similiar
> >>>>>> languages we have to implement it using getter methods). Luckily
> >>>>>> Javascript doesn't need getter and setters methods to make a
> >>>>>> property overridable because of getter and setters descriptors,
> >>>>>> so we can workaround the first example
> >>>>>> easily:
> >>>>>>
> >>>>>> ``` js
> >>>>>> class Bar {
> >>>>>> bar = 'in bar';
> >>>>>>
> >>>>>> constructor() {
> >>>>>> console.log(this.bar)
> >>>>>> }
> >>>>>> }
> >>>>>>
> >>>>>> class Foo extends Bar {
> >>>>>> _initiedSuper = false;
> >>>>>> _bar = 'in foo';
> >>>>>>
> >>>>>> constructor() {
> >>>>>> super();
> >>>>>> this._initiedSuper = true;
> >>>>>> }
> >>>>>>
> >>>>>> get bar() {
> >>>>>> return this._bar;
> >>>>>> }
> >>>>>>
> >>>>>> set bar(val) {
> >>>>>> if (this._initiedSuper) {
> >>>>>> this._bar = val;
> >>>>>> }
> >>>>>> }
> >>>>>> }
> >>>>>>
> >>>>>> new Foo(); // will log 'in foo'
> >>>>>> ```
> >>>>>>
> >>>>>> *I have to say the relaying that the super constructor will use
> >>>>>> the bar property and workarounding it **is a bad practice** and
> >>>>>> should be avoided at any costs. The contract with the super class
> >>>>>> constructor should rely only on the super call, these situations
> >>>>>> just reveal bad design choices in the super class. Logan Smyth
> >>>>>> example is the correct answer to this problem*
> >>>>>>
> >>>>>>
> >>>>>> 25-08-2018 01:28, Jordan Harband <[email protected]>:
> >>>>>>
> >>>>>> >
> >>>>>> > Personally I think a design where the superclass relies on any
> >>>>>> > part of the subclass is "broken by design"; but certainly
> >>>>>> > there's ways you can achieve that.
> >>>>>> >
> >>>>>>
> >>>>>> Of course is not broken. The super class has a contract with a
> >>>>>> parametrized option, it can be used in subclasses or just in a
> >>>>>> constructor call `new Base({ idAttribute: 'foo' })`, if it has a
> >>>>>> default value for that is not a sub class concern. When
> >>>>>> refactoring code adding defaults and "lifting" parameters are
> >>>>>> very common ~not only on OOP~ and relying that the super class is
> >>>>>> using some property in the constructor is the real "broken by
> design".
> >>>>>> _______________________________________________
> >>>>>> es-discuss mailing list
> >>>>>> [email protected]
> >>>>>> https://mail.mozilla.org/listinfo/es-discuss
> >>>>>
> >>>>> _______________________________________________
> >>>>> es-discuss mailing list
> >>>>> [email protected]
> >>>>> https://mail.mozilla.org/listinfo/es-discuss
> >>
> >> _______________________________________________
> >> es-discuss mailing list
> >> [email protected]
> >> https://mail.mozilla.org/listinfo/es-discuss
>
>
>
> ---
> This email has been checked for viruses by AVG.
> https://www.avg.com
>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss