views:

70

answers:

2

is there a way to tear down a closure in JavaScript to determine what the function is and what the scope is?

Or, maybe more succinctly, is there a way to serialize a closure in JavaScript?

edit

What I am wondering if I am given a function declared as follows:

var o = {};
var f = function() { return o; }

Is there a way to look at just f and find o?

+3  A: 

I'm not sure what you mean by "tear down a closure". Determining what the function is can be done using arguments.callee:

function test () { console.log(arguments.callee); }
// -> function test () { console.log(arguments.callee); }

and what the scope is?

The only real way to check to see if a variable is in scope is by trying to access it. That means you need to use a try/catch statement, because an error is thrown if you refer to an undeclared variable:

try{ myVar; alert("myVar is in scope"); }catch (e){ alert("myVar is not in scope"); }

Realistically you would already know which variables are in scope if you wrote the code or even by examining the code if you didn't write it.

If you're trying to get the stack, you can (sort of) do this using the caller property, but it's non-standard and might not be available in all JS implementations*:

function getStack () {
    var stack = [], cFunc = arguments.callee;
    while (cFunc = cFunc.caller)
        stack.push(cFunc);

    console.dir(stack);
}

function func1 () { func2(); }
function func2 () { try { obviousError(); } catch (e) { getStack(); } }

Most built-in developer tools give you the stack (IE 7 and IE 8 don't) in a much clearer manner, so it's best to use them where possible.

* Currently all major browsers support Function.caller. It also appears that it is defined in ECMAScript 3.1 - you can check support here.

Andy E
+1  A: 

If I understand you correctly (it's hard to tell, even with your latest edit), the answer is no. One of the purposes of closures is to encapsulate variables, limiting accessibility to groups of related/dependent code (assigned out of the global context), in an effort to minimize name conflicts and/or accidental interaction. If you want to access o in a global context, then you should define it there instead.

Josh Stodola
Basically, I'm looking for a way to serialize a closure to a string so the continuation can live on past a page refresh.
MathGladiator
@MathGladiator What does that have to do with closures? What you are saying makes little sense to me.
Josh Stodola