I'm trying to use Javascript Proxy
objects to trap the arguments that are passed to a 'method' of the target that I'm proxying.
Please consider this example:
var test = {
doSomething: function() {
console.log( arguments.length );
}
};
var testProxy = new Proxy( test, {
get: function( target, property, receiver ) {
// I'd like to have access to any arguments when
// the property being accessed here is a function
// that is being called
return target[ property ];
}
} );
testProxy.doSomething( 'this', 'is', 'lame' ); // I want to trap those arguments
It appears that these Proxy
objects only allow you to trap accessing the property, but not the actual function call, with its arguments, when the property is in fact a function.
After reflecting a bit on the matter, I "get" (pardon the pun) that the get
method is just intended for property access, in stead of invocation, but then I would have expected to be able to define something like a call
method in the Proxy
as well.
Perhaps it's doable with defining an apply
method in the Proxy
, but then I'd probably have to create a Proxy
object for each individual method of the object I want to proxy; and that's not what I am after.
Unless I'm overlooking an actual alternative possibility here: how is it that this is overlooked in the Proxy
implementation?! Isn't the whole point of a proxy to be able to intercept method calls and their arguments as well?
Or is this yet another misunderstanding of Javascript, on my part, about Javascript not being a 'classical' OOP language, and that the functionality I'm looking for wouldn't actually make sense in the context of Javascript?
There actually is a way to do this, of course! I just hadn't thought it through thoroughly enough. I can just return a 'proxy' function and trap the arguments in there:
var test = {
doSomething: function() {
console.log( arguments.length );
}
};
var testProxy = new Proxy( test, {
get: function( target, property, receiver ) {
switch( property ) {
case 'doSomething':
// you just have to return a proxy function
return function() {
// arguments accessible, after all!
console.log( 'testProxy::doSomething() arguments.length: ' + arguments.length );
// here you can still invoke the original method, of course
target[ property ].apply( this, arguments );
}
break
}
return target[ property ];
}
} );
testProxy.doSomething( 'this', 'is', 'not', 'so', 'lame', 'after', 'all' );