`field = (function () { return class { }; }())` - how exactly would you propose banning creating a class inside class fields?
On Mon, Sep 3, 2018 at 12:05 PM, Ranando King <king...@gmail.com> wrote: > 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 > >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss