Proxy handler.has() does not have a receiver argument?

#!/JoePea joe at trusktr.io
Fri Nov 22 17:36:58 UTC 2019


HI Cyril, thanks for pointing that out! I know about those, I've been using
class-factory mixins for a while now. But the problem with them is having
to wrap all your classes in a function, which gets much more painful in
TypeScript with all the type-annotation boilerplate that is required.

For example, here's a boilerplate-heavy mixin of mine:

- Header:
https://github.com/infamous/infamous/blob/develop/src/core/ImperativeBase.ts#L55
- Footer:
https://github.com/infamous/infamous/blob/develop/src/core/ImperativeBase.ts#L615
- Mixin helper application (provides mixin result caching, deduplication,
Symbol.hasInstance, etc):
https://github.com/infamous/infamous/blob/develop/src/core/ImperativeBase.ts#L662
- The type system that I imported from my lowclass lib:
https://github.com/infamous/infamous/blob/develop/src/core/ImperativeBase.ts#L2

Multiple inheritance with Proxies actually turns out very easy to type in
TypeScript, and a lot more convenient than class factories. So, given a set
of regular classes,

```js
class One {
  doOne() { /* ... */ }
}

class Two {
  doTwo() { /* ... */ }
}

class Three {
  doThree() { /* ... */ }
}
```

a Proxy-based multiple inheritance system makes the composition super easy,
clean, and simple. We can convert the previous example into:

```js
import mix from './mix'

class One {
  doOne() { /* ... */ }
}

class Two {
  doTwo() { /* ... */ }
}

class Three extends mix(One, Two) {
  doThree() { /* ... */ }
  doAll() {
    this.doOne()
    this.doTwo()
    this.doThree()
  }
}
```

All without touching the original source of the `One` and `Two` classes.
How convenient, and easier to read and look at!

My particular implementation will allow to call individual constructors
with specific args, unlike the class-factory mixins. For example,

```js
import mix from './mix'

class One {
  constructor(arg1, arg2) {/*...*/}
  doOne() { /* ... */ }
}

class Two {
  constructor(arg3) {/*...*/}
  doTwo() { /* ... */ }
}

class Three extends mix(One, Two) {
  constructor(arg1, arg2, arg3) {
    this.callConstructor(One, arg1, arg2)
    this.callConstructor(Two, arg3)
  }
  doThree() { /* ... */ }
  doAll() {
    this.doOne()
    this.doTwo()
    this.doThree()
  }
}
```

At the moment I'm looking to convert from my Proxies-on-prototypes
implementation to Proxies-on-instances so that things like `in` operator
will work, and implementation will be simpler and easier. Otherwise if the
`has` trap had a `receiver` parameter, then I could stick with the
Proxies-on-prototypes version which would be more efficient (the Proxy
would be re-used on the prototype chain instead of being created once per
instance).

Would it be worth adding a `receiver` parameter to the `has` trap in the
specs? Seems like it would be totally backwards compatible, because current
code that doesn't rely on it could continue not relying on it oblivious to
the new parameter.

All the best,
- Joe

On Fri, Nov 22, 2019 at 3:55 AM Cyril Auburtin <cyril.auburtin at gmail.com>
wrote:

> It's not answering your issue with Proxy but more about multiple
> inheritance
>
> It can be solved in a static way:
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Mix-ins
>
> Concrete example here:
> https://github.com/pepabo/gmopg/blob/master/src/gmopg.ts#L10
>
> On Fri, Nov 22, 2019 at 4:23 AM #!/JoePea <joe at trusktr.io> wrote:
>
>> After messing with Proxy-on-prototypes for two days, I've just come to
>> the conclusion that I probably need to have Proxies on this (the
>> receiver) returned from constructors to achieve what I want. At least,
>> it's much easier to code it that way. I think it'd be nice to have
>> receiver on all inheritance-related traps. That might make some things
>> easier.
>>
>> On Thu, Nov 21, 2019 at 2:55 PM #!/JoePea <joe at trusktr.io> wrote:
>> >
>> > I really thing that because `has` is about detecting inherited
>> > properties, the `receiver` parameter should be included. For things
>> > like `ownKeys`, which are not about inheritance, then yeah, let's not
>> > add receiver there.
>> >
>> > I'm trying to implement my own multiple inheritance, but now I
>> > stumbled on how to make it send back true for inherited keys when I
>> > need to fork the lookup based on instances that are `WeakMap`ed to the
>> > `receiver`.
>> _______________________________________________
>> 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/20191122/a6f66fdc/attachment-0001.html>


More information about the es-discuss mailing list