Search code examples
javascriptnode.jsecmascript-6es6-proxy

Using ES6 Proxy results in any function call "is not a function"


I was trying to be a sneaky developer, and I done got myself lost in ES6 Proxies. Basically I wanted to capture any get or set in a property from another class I wrote and make sure they are stored somewhere else besides the object. It looks like this:

'use strict'
class MyObject()
{
    superAwesomeFunction(){//super awesome code goes here}
}

const myProxyObject = new Proxy(MyObject, {
get: function(target, name, receiver)
{
    if([CONDITIONS THAT MEET MY DEMANDS])
    {
         // deliver property values if they are
         // my super cool database (if they exist)
    }

    // else just ya know, forward it to the actual MyObject
    // property, if it's an actual property on MyObject
    return target[name];
},
set: function(target, name, value)
{
    if([CONDITIONS THAT MEET MY DEMANDS])
    {
         // set property values if they are
         // to super cool database
    }
    else
    {
        // just set the value to the property, which
        // gets created if it doesn't exist (WHICH IS SO COOL)
        target[name] = value;
    }
    return true;
}

Okay the cool part about this? you can do something like:

// property that doesn't exist (yet)
console.log(myProxyObject.wholivesinapineappleunderthesea);

// but wait for it...
myProxyObject.wholivesinapineappleunderthesea = 'spongebob';

// bam! now it exists on the object, AND lives in my DB!
console.log(myProxyObject.wholivesinapineappleunderthesea);

Which, while a lot of work for something dorky, i cannot explain how happy it makes me feel. However, there is a problem with this. Remember that superAwesomeFunction() I put in MyObject()? Well whenever I try to call it now ES6 gives me this load of sadness:

myProxyObject.superAwesomeFunction is not a function

ES6 sits on a throne of LIES! It's totally there right? Okay so I'm pretty sure I'm trapping something wrong, because when I debug I see that the get section of the Proxy is actually picking up the superAwesomeFunction call (which makes sense as superAwesomeFunction is a property that contains a function (){})

HERE'S MY QUESTION: Does anybody know of any solution that will let me keep my ridiculous on the fly properties and still call my superAwesomeFunction()? Is it the apply trap?


Solution

  • It is a little syntax error there ... you are wrapping the proxy around the raw class, not an object.

    Try:

    const myProxyObject = new Proxy(new MyObject(), { ... });
    

    This should be ok. For example:

    > class Blah {
    ... run() {
    ..... console.log('yay')
    ..... }
    ... }
    [Function: blah]
    > myProx = new Proxy(new Blah(), {});
    blah {}
    > myProx.run()
    yay