Skip to content

Instantly share code, notes, and snippets.

@madbook
Created December 20, 2012 14:56
Show Gist options
  • Save madbook/4345727 to your computer and use it in GitHub Desktop.
Save madbook/4345727 to your computer and use it in GitHub Desktop.
Function for detecting variable leaks at runtime. Could also be used to do 'dry run' method calls, to see what properties of their object they will change. Works by cloning the window object, calling the function, comparing, then reverting any changes to the window. Practical? Not really. Kind of neat though.
/**
* catches any modifications to the given object (usually the global/window)
* object, and places them in a 'trap' object. Can prevent variable leak
* from missing var statements, as well as any modifications to the 'this'
* object inside of the function.
* @param {Object} t - trap object to use. Its necessary to pass in instead
* of returning because we still might want the return
* value of the function we're calling.
* @param {Function} f - function to call
* @param {Object} c - context to call function in. this is also the object
* that we are checking changes against. In most cases
* this would be the global object or an instance of an
* object (if the function is a method)
* @param {Array} a - an array of arguments to pass to the function
* @return {*} - the return value from function f
*/
function catchleaks(t, f, c, a) {
var _c = {}, u = {}, i;
for (i in c) {
// copy the object c
_c[i] = c[i];
// have to note properties of window that are set to undefined
if (c[i]===undefined)
u[i]=1;
}
// call the function f
var r = f.apply(c, a);
// compare object c to copy, put changes in object t
for (i in c) {
if (typeof _c[i] === 'undefined' && typeof u[i] === 'undefined') {
// wasn't in window, delete it
t[i] = c[i];
delete c[i];
} else if (_c[i] !== c[i]) {
t[i] = c[i];
c[i] = _c[i];
}
}
// return from function f
return r;
}
/**
* testing catchleaks function
*/
window.testA = 1;
function leaky(c) {
testA = 'A';
testB = 'B';
testC = c;
}
var trap = {}; // trap has to be defined outside of the function call, so we can access the changed properties.
catchleaks(trap, leaky, window, ['C']);
console.log(window.testA === 1); // true
console.log(typeof window.testB === 'undefined'); // true
console.log(typeof window.testC === 'undefined'); // true
console.log(trap.testA === 'A'); // true
console.log(trap.testB === 'B'); // true
console.log(trap.testC === 'C'); // true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment