nx-js / observer-util

Transparent reactivity with 100% language coverage. Made with ❤️ and ES6 Proxies.
MIT License
1.2k stars 94 forks source link

`construct` trap fails for observed constructors #48

Open justinweiss opened 4 years ago

justinweiss commented 4 years ago

Hi! Thanks so much for the library, it's been great to use.

We've been trying 4.3.0-alpha.2 to get the react-easy-state fix https://github.com/RisingStack/react-easy-state/issues/184, and ran into a problem using constructors that have been observed -- at least with @babel/plugin-transform-classes. I haven't been able to test without it, but either way the behavior doesn't seem right.

An example might be easiest:

class Thing {}

const thing = new Thing(); // => Thing instance
const observableThing = observable(thing); // => Proxy wrapping Thing instance
const Constructor = observableThing.constructor; // => Proxy wrapping Thing()
const newThing = new Constructor(); // => Fails with Uncaught TypeError: Cannot call a class as a function

The failure happens because the construct function here is called as

construct(Thing, [], Proxy { Thing() })

When constructing the object, Thing() is called with this set to Proxy { Thing() }.prototype, which is also a Proxy. This means that this instanceof Thing will be false, which seems incorrect.

I think using the raw constructor as newTarget would be the easiest fix, but I don't know whether that's right.

ximing commented 4 years ago

I had the same problem If use the raw constructor as newTarget, it seems that the unit test could pass。