Symbol for modifying property lookup?

/#!/JoePea joe at trusktr.io
Wed Jul 13 20:04:59 UTC 2016


Thanks kdex.

In one of my cases, `A` extends `B` extends `C` just so that `A` can have
characteristics of both `B` and `C`, but it doesn't actually make sense for
`B` to extend `C` because `B` is not a more specific form of `C` -- `B` and
`C` are completely unrelated classes; I'm extending `B` from `C` just for
`A` to have both sets of characteristics.

How might decorators be used instead?

I found some good reading:

-
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Mix-ins
- http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/

I am currently reading to get ideas on what I might do, but would love
suggestions if you have any.

*/#!/*JoePea

On Wed, Jul 13, 2016 at 3:00 AM, kdex <kdex at kdex.de> wrote:

> Callable class constructors [1] have been discussed at some point.
> They've been withdrawn [2] in favor of decorators [3], though.
>
> [1]
> https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md
> [2]
> https://github.com/tc39/proposals/blob/master/inactive-proposals.md#inactive-proposals
> [3] https://github.com/wycats/javascript-decorators/blob/master/README.md
>
> On Wednesday, July 13, 2016 2:24:10 AM CEST /#!/JoePea wrote:
> > Oops, I forgot that ES6 classes can't be called using the
> > `SomeClass.call(...)` form. Is there a workaround for that so that my
> > constructor can call all of them (besides downgrading to ES5 classes)?
> >
> > ```js
> > class Foo extends new MultiClass(One, Two) {
> >   constructor(...args) {
> >     One.call(this, ...args)
> > ​ // Error, not allowed​
> >
> >
> > ​Two​
> > .call(this, ...args)​ //
> > ​Error​
> > , not allowed
> > ​​
> >   }
> > }
> > ```
> >
> > */#!/*JoePea
> >
> > On Wed, Jul 13, 2016 at 1:49 AM, /#!/JoePea <joe at trusktr.io> wrote:
> >
> > > Thanks guys, Proxy is the one, but not supported natively enough yet
> > > unfortunately.
> > >
> > > Here is the ES5 solution I came up with, which creates "proxy" methods
> on
> > > the "multiPrototype" of the new MultiClass:
> > >
> > > ```js
> > > class MultiClass {
> > >     constructor(...constructors) {
> > >         let constructorName = ''
> > >         let multiPrototype = {}
> > >
> > >         console.log(' -- Creating new MultiClass.')
> > >
> > >         for (let i=0, l=constructors.length; i<l; i+=1) {
> > >             const constructor = constructors[i]
> > >
> > >             constructorName += constructor.name + (i == l-1 ? '' :
> '+')
> > >             // f.e. SomeClass_OtherClass_FooBar
> > >
> > >             let props =
> > >
> SimplePropertyRetriever.getOwnAndPrototypeEnumerablesAndNonenumerables(constructor.prototype)
> > >             for (let prop of props) {
> > >                 multiPrototype[prop] = constructor.prototype[prop]
> > >                 console.log(' --- prop', prop)
> > >             }
> > >         }
> > >
> > >         // temporary object to store the new MultiClass constructor,
> > > because
> > >         // using an object allows us to programmatically assign a name
> to
> > > the
> > >         // function, which we otherwise cannot do without eval().
> > >         let tmp = {
> > >
> > >             // This new constructor doesn't do much, just has all the
> given
> > >             // constructor prototypes mixed in to it's own prototype.
> Be
> > > sure to
> > >             // call the each constructor manually in the class that
> > > extends this
> > >             // new MultiClass.
> > >             [constructorName]() {}
> > >
> > >         }
> > >
> > >         tmp[constructorName].prototype = multiPrototype
> > >
> > >         return tmp[constructorName]
> > >     }
> > > }
> > > ```
> > >
> > > Where `SimplePropertyRetriever` is taken from the MDN article
> > > [Enumerability and ownership of properties](
> > >
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#Obtaining_properties_by_enumerabilityownership
> > > ).
> > >
> > > Example usage:
> > >
> > > ```js
> > > class One {
> > >     foo() {console.log('foo')}
> > > }
> > >
> > > class Two {
> > >     constructor() {/* ... */}
> > >     bar() {console.log('bar')}
> > > }
> > >
> > > class Three extends Two {
> > >     constructor(...args) {
> > >         super(...args)
> > >         // ...
> > >     }
> > >     baz() {console.log('baz')}
> > > }
> > >
> > > class FooBar extends new MultiClass(Three, One) {
> > >     constructor(...args) {
> > >         super() // needed, although does nothing.
> > >
> > >         // call each constructor.
> > >         One.call(this, ...args)
> > >         Three.call(this, ...args)
> > >     }
> > >     oh() {console.log('oh')}
> > >     yeah() {console.log('yeah')}
> > > }
> > >
> > > let f = new FooBar
> > >
> > > f.foo()
> > > f.bar()
> > > f.baz()
> > > f.oh()
> > > f.yeah()
> > > ```
> > >
> > > Any ideas on how else to do it?
> > >
> > > */#!/*JoePea
> > >
> > > On Tue, Jul 12, 2016 at 1:52 AM, Claude Pache <claude.pache at gmail.com>
> > > wrote:
> > >
> > >>
> > >> Le 12 juil. 2016 à 02:45, /#!/JoePea <joe at trusktr.io> a écrit :
> > >>
> > >> Does one exist? I'm imagining an implementation for
> > >>
> > >> ```
> > >> class Node extends new MultiClass(ImperativeBase, Transformable) {
> > >> }
> > >> ```
> > >>
> > >>
> > >> I think that  Proxy is the tool for that purpose.
> > >>
> > >> How a symbol would work here, since you need a property lookup in
> order
> > >> to find that symbol?
> > >>
> > >> —Claude
> > >>
> > >
> > >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160713/2e1f7e85/attachment-0001.html>


More information about the es-discuss mailing list