Javascript construct trap not working in class returning proxy

138 Views Asked by At

I am trying to create a little javascript two way form binder using proxies. I am stuck on how I can intercept 'new' calls. I use a 'construct' trap but it doesn't fire. Here is my code, I have removed the stuff that is not relivant for my specific problem

    class BoundObject {

        constructor(object, element) {

            // distribute object properties into "this"
            for (const prop in object) {
                this[prop] = object[prop]
            }

            return new Proxy(this, {

                construct:(target, args) => {
                    console.log(`Creating a new ${target.name}`) // why is this not fired?
                    return Reflect.construct(...args)
                },
                set: (target, prop, val, receiver) => {
                    console.log(`attempting to set ${prop}=${val} type ${typeof val}`);

                    return Reflect.set(target, prop, val) 
                }
            })
        }
    }

    // create an instance of our BoundObject class, passing in an object and an HTML element
    const user = new BoundObject({name:'fred'},document.querySelector('#user-form'))    // why is the 'construct' call not intercepted?
    user.name = 'mary' // set user name. The 'set' call is sucessfully intercepted

The set trap works, but the construct trap fails to fire. I suspect this is to do with javascript deep magic around 'this' but cannot figure it out

How can I intercept the construction of the proxy object my class returns?

1

There are 1 best solutions below

1
Unmitigated On BEST ANSWER

The construct trap is only called when the [[Construct]] internal method is invoked on the proxy itself. This could be caused by using the new operator. However, in this case, the Proxy is returned as a result of calling new on the BoundObject constructor; new was not called on the proxy itself.

Here is an example of where the construct trap could be called.

function MyObj() {}
const proxy = new Proxy(MyObj, {
  construct(target, args) {
    console.log(args);
    return new target(...args);
  }
});
new proxy('something');