constructor, super, and data members issue
Logan Smyth
loganfsmyth at gmail.com
Sun Aug 26 19:20:35 UTC 2018
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 <isiahmeadows at 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 <therealbenwiley at 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 <isiahmeadows at 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 <therealbenwiley at 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.borgesm at gmail.com>
>>>> a écrit :
>>>>
>>>>> 24-08-2018 19:29, Aaron Gray <aaronngray.lists at 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 <ljharb at 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 at mozilla.org
>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> es-discuss at mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>> _______________________________________________
> 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/20180826/54c9d136/attachment-0001.html>
More information about the es-discuss
mailing list