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?
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?
Share Improve this question edited Jun 3, 2023 at 17:33 dumbass 27.3k4 gold badges38 silver badges74 bronze badges asked Apr 21, 2017 at 16:01 Kyle KinkadeKyle Kinkade 1671 silver badge13 bronze badges 2-
1
You need to do
const myProxyObject = new Proxy(new MyObject(), {...})
. – idbehold Commented Apr 21, 2017 at 16:23 - The sample code is not even valid syntax. – dumbass Commented May 11, 2024 at 19:03
3 Answers
Reset to default 4To extend on Sam's answer.
The following succeeds:
function Foo() {
this.bar = function() { console.log('baz'); }
}
let foo = new Proxy(new Foo(), {});
foo.bar();
However, when the get
trap is added to the handler, "is not a function" is thrown:
function Foo() {
this.bar = function() { console.log('baz'); }
}
let foo = new Proxy(new Foo(), {
get: function(target, prop) {}
});
foo.bar();
The solution here is to add a typeof
check for default handling of the target's existing functions:
function Foo() {
this.bar = function() { console.log('baz'); }
}
let foo = new Proxy(new Foo(), {
get: function(target, prop) {
if (typeof target[prop] === 'function') {
return target[prop].bind(target);
}
}
});
foo.bar();
The following articles gives some more examples and provides nice boilerplate to use with Proxy handlers: Safely Extending The JavaScript Set Object Using Proxies
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
Full code for answer is here, thank you everyone!
'use strict'
class MyObject()
{
superAwesomeFunction(){
console.log("this works!");
}
}
const myProxyObject = new Proxy( new MyObject(), {
get: function(target, name, receiver)
{
if([CONDITIONS THAT MEET MY DEMANDS])
{
// do something cool for yourself
}
return target[name];
},
set: function(target, name, value)
{
if([CONDITIONS THAT MEET MY DEMANDS])
{
// do something cool for yourself
}
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;
}
});