Skip to content

Instantly share code, notes, and snippets.

@jeffschwartz
Last active June 19, 2021 14:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeffschwartz/8375965 to your computer and use it in GitHub Desktop.
Save jeffschwartz/8375965 to your computer and use it in GitHub Desktop.
ProxyJS is a small JavaScript library that provides the ability to proxy any function or object property method. It includes an API and you can extend it with additional functionality to fit your particular use case. Enjoy!
function proxy(){
var proxyFactory = function(){
//The wrapped function to call.
var fnToCall = arguments.length === 2 ? arguments[0][arguments[1]] : arguments[0];
//A counter used to note how many times proxy has been called.
var xCalled = 0;
//An array of arrays used to note the arguments that were passed to proxy.
var argsPassed = [];
//An array whose elements note what the wrapped function returned.
var returned = [];
///
///Privileged functions used by API
///
//Returns the number of times the wrapped function was called.
var getCalledCount = function(){
return xCalled;
};
//If called with 'n' and 'n' is within bounds then returns the
//array found at argsPassed[n], otherwise returns argsPassed.
var getArgsPassed = function(){
if(arguments.length === 1 && arguments[0] >= 0 && arguments[0] < argsPassed.length){
return argsPassed[arguments[0]];
}else{
return argsPassed;
}
};
//If called with 'n' and 'n' is within bounds then returns
//value found at returned[n], otherwise returns returned.
var getReturned = function(){
if(arguments.length === 1 && arguments[0] >= 0 && arguments[0] < returned.length){
return returned[arguments[0]];
}else{
return returned;
}
};
//If 'n' is within bounds then returns an
//info object, otherwsie returns undefined.
var getData= function(n){
if(n >= 0 && n < xCalled){
var args = getArgsPassed(n);
var ret = getReturned(n);
var info = {
count: n + 1,
argsPassed: args,
returned: ret
};
return info;
}
};
//A higher order function - iterates through the collected data and
//returns the information collected for each invocation of proxy.
var dataIterator = function(callback){
for(var i = 0; i < xCalled; i++){
callback(getData(i));
}
};
//The function that is returned to the caller.
var fn = function(){
//Note the arguments that were passed for this invocation.
var args = [].slice.call(arguments);
argsPassed.push(args.length ? args : []);
//Increment the called count for this invocation.
xCalled += 1;
//Call the wrapped function noting what it returns.
var ret = fnToCall.apply(this, args);
returned.push(ret);
//Return what the wrapped function returned to the caller.
return ret;
};
///
///Exposed Lovwer level API - see Privileged functions used by API above.
///
fn.getCalledCount = getCalledCount;
fn.getArgsPassed = getArgsPassed;
fn.getReturned = getReturned;
fn.getData = getData;
///Exposed Higher Order API - see Privileged functions used by API above.
fn.dataIterator = dataIterator;
///Replaces object's method property with proxy's fn.
if(arguments.length === 2){
arguments[0][arguments[1]] = fn;
}
//Return fn to the caller.
return fn;
};
//Convert arguments to an array, call factory and returns its value to the caller.
var args = [].slice.call(arguments);
return proxyFactory.apply(null, args);
}
@jeffschwartz
Copy link
Author

@lakuapik
Copy link

Please see http://adoseofjavascript.com/2014/01/11/proxyjs-a-javascript-proxy-library/ for more details.

the link is broken.

@jeffschwartz
Copy link
Author

@lakuapik unfortunately that blog is no longer available. If you have a question about ProxyJS I will try to answer it here. BTW if I were to write this little proxy library today it would be greatly simplified by using the numerous modern javascript features found in ES6+.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment