Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I trap arguments to a target method when using a Proxy object?

Tags:

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?

like image 211
Decent Dabbler Avatar asked Jul 31 '14 21:07

Decent Dabbler


People also ask

What does a proxy do to the target object 1 point?

A JavaScript Proxy is an object that wraps another object (target) and intercepts the fundamental operations of the target object. The fundamental operations can be the property lookup, assignment, enumeration, and function invocations, etc.

What is a proxy target?

target : the original object which you want to proxy. handler : an object that defines which operations will be intercepted and how to redefine intercepted operations.

What is trap in JavaScript?

Traps are internal method detection tools. Whenever you interact with an object, you are calling an essential internal method. Proxies allow you to intercept the execution of a given internal method. So when you run: const profile = {}; profile.

What is the use of proxy object in JavaScript?

In JavaScript, proxies (proxy object) are used to wrap an object and redefine various operations into the object such as reading, insertion, validation, etc. Proxy allows you to add custom behavior to an object or a function.


2 Answers

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' ); 
like image 115
Decent Dabbler Avatar answered Sep 17 '22 19:09

Decent Dabbler


another snippet : )

const obj_hidden = {};  const obj = new Proxy(obj_hidden, {     get(target, prop) {         if (typeof target[prop] == 'function') {           return function (...args) {             console.dir({ call: [prop, ...args] });             return target[prop].apply(target, args);           }         }         console.dir({ get: prop });         return target[prop];     },     set(target, prop, value) {         console.dir({ set: [prop, value] });         target[prop] = value;         return true;     } }); 
like image 34
Mila Nautikus Avatar answered Sep 18 '22 19:09

Mila Nautikus