That scenario is intentional. I see no need to ban it. I would only want to ban the confusing case of direct assignment in the outer class declaration. For cases where the user intentionally defines a class as you have done, they should know that what they've done will create a class that is persistently re-defined with each instance. As has been said many times before, it's good to reduce the number of foot-guns, but at some point, you have to expect some level of responsibility from the programmer. Consider that rule as little more than a safety switch.
On Mon, Sep 3, 2018 at 3:52 PM Jordan Harband <[email protected]> wrote: > `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 <[email protected]> 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 <[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 >> >> >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

