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 <dooda...@gmail.com> 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 <isiahmead...@gmail.com> > Sent: Sunday, August 26, 2018 3:29 PM > To: Logan Smyth <loganfsm...@gmail.com> > Cc: Ben Wiley <therealbenwi...@gmail.com>; es-discuss < > es-discuss@mozilla.org> > 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 > cont...@isiahmeadows.com > www.isiahmeadows.com > > On Sun, Aug 26, 2018 at 12:20 PM Logan Smyth <loganfsm...@gmail.com> > 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 <isiahmead...@gmail.com> > 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 <therealbenwi...@gmail.com> > 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 <isiahmead...@gmail.com> > 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 <therealbenwi...@gmail.com> > 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 < > augusto.borg...@gmail.com> a écrit : > >>>>>> > >>>>>> 24-08-2018 19:29, Aaron Gray <aaronngray.li...@gmail.com>: > >>>>>> > >>>>>> > > >>>>>> > 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 <ljh...@gmail.com>: > >>>>>> > >>>>>> > > >>>>>> > 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 > >>>>>> es-discuss@mozilla.org > >>>>>> https://mail.mozilla.org/listinfo/es-discuss > >>>>> > >>>>> _______________________________________________ > >>>>> es-discuss mailing list > >>>>> es-discuss@mozilla.org > >>>>> https://mail.mozilla.org/listinfo/es-discuss > >> > >> _______________________________________________ > >> es-discuss mailing list > >> es-discuss@mozilla.org > >> https://mail.mozilla.org/listinfo/es-discuss > > > > --- > This email has been checked for viruses by AVG. > https://www.avg.com > > _______________________________________________ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss