10

For example, if we assume the following code:

var f = function() { return 'hello world' };
var x = 10;
var y = 314;

var g = function() {
    var buf = [], xx = x;
    while (xx--)
        buf.append(f() + ' ');
    return buf.join('');
}

I can get the actual "code" as a string of g with g.toString(). However, this does not (obviously) get f and x—members of the closure of g (sorry if I'm not quite using these terms correctly.)

Is there some way to query a function for what its closure contains? Ideally I could get an object like:

{ 'f' : f, 'x': x } // note that `y` is not here

If I have to drop into C++ for special interactions with V8, that's okay—although somehow doing this in pure JavaScript would be best.


I know that this is a bit of an odd question—but I do have a legitimate reason for wanting this!

8
  • I'm a bit confused about your desired ideal result. You want to see an object that has 'f' and 'g' but not 'y', and you don't mention 'x' at all (even though it's declared in the same scope as f, g and y)? One way of interpreting "closure of g" could be to give a list of all variables/functions that the function g() has access to...
    – nnnnnn
    Commented Aug 15, 2011 at 4:34
  • The x thing was my fault. Wasn't thinking correctly. And f is a member because it is required for g to run ( buf.append(f()...) ) just like x is a member for the same reason. Commented Aug 15, 2011 at 4:36
  • Instead of "has access to", I'd like to use "actually uses". Hence why y is not there. Commented Aug 15, 2011 at 4:40
  • 1
    I'm not aware of any easy way to do that, and I wouldn't want to do it the hard way (parsing the text of the function looking for variables not defined within the function).
    – nnnnnn
    Commented Aug 15, 2011 at 4:52
  • 1
    V8 must somehow track this information internally for closures to actually work, right? Commented Aug 15, 2011 at 4:55

5 Answers 5

5

I found this discussion of V8 closure implementations enlightening. It sounds like the C++ object you're looking for is a Context.

1
  • Hi, Hurry, could you tell me how to get the Context object from a v8::Function object? Thanks in advance.
    – Pylipala
    Commented Jun 4, 2015 at 2:27
0

You want to have a list of all variables that get used inside that function, right? The quick and dirty way would probably be to use something like the parser and AST stuff from UglifyJS to walk the function so that you can then get a list of all variables and so on.

1
  • There would be no way to get the value of those variables (a reference to the object they point to) right, assuming you could get their names via an tokenizer? Commented Aug 15, 2011 at 22:54
0

Edit:

Such method does not exist. If you're hellbent on doing this in JavaScript then your best bet would be to write a parser that would determine what variables a function closes over.

If you write such a method, please share :)

Original post:

In your example the closure g has access to f and y. x is being declared as a local variable therefore x does NOT equal 10. There isn't a special method that will tell you what variables a function closes over.

If g was a method of an object you could use hasOwnProperty function of object to determine what properties are available to the object. AFAIK that's the only thing that comes close to determining what variables a function has access to in JavaScript.

4
  • I obviously didn't look over my sample code closely enough! x issue fixed. And what I'm saying is that the actual V8 engine must keep track of this information somewhere (so that the function can be called correctly etc). Commented Aug 15, 2011 at 14:13
  • That sounds correct and it's out of my scope. I'm sure there isn't a JavaScript method specifically for this purpose although I'm sure you could write a parser for this purpose :) Commented Aug 15, 2011 at 19:40
  • If you went the parse route, there wouldn't be any way to get actual references to the objects along with their names would there be? Commented Aug 16, 2011 at 0:22
  • Yes there would. WebInspector for WebKit seems to be doing something like this already, but they do it in C AFAIK and pass the results to JS. Would be nice to check out their code. WebKit and WebInspector are both open source projects. Commented Aug 18, 2011 at 0:10
-2

There is no closures present in the code you posted. You can get the value of any variable you want at any point and that will be what your g function sees. Just because you call a function from within another function does not make a closure. For there to be a closure f would have to be a variable of the g function scope and it is not. Both of these functions are in the same scope as your x and y, presumably the global. If you were to say wrap that whole puppy up into one larger function they would all still be in the same scope but if you were to return f and g from an encompassing function, then you would be looking at a closure where x and y would be private to the returning function, shared with f and g. Then you would need some form of getter function which would also need to be returned and could communicate by setting the value of an observing variable up one link in the scope chain.

As it stands now, with the code presented, x is x and y is why, check them anytime you want and that is their value, which is also what both f and g would see.

Ricky Gee

1
  • f, x and y are all members of g's closure. x, y and g are all members of f's closure. Any time you create a literal function in js, you create a closure.
    – mako-taco
    Commented Sep 20, 2013 at 17:22
-3

As Ricky Gee said, there is no problem here, because the variables are all global, so you can get to them through the global object. However, if we assume that the code was not global, then no, you can't extract a reference to the variables f, x and y (nor their values) from the closure of g.

You can't do it in JavaScript, and you can't do it through the V8 API. Obviously, the data is somewhere, but V8 doesn't even try to make its internal data structures available.

2
  • You can access the closure in v8 through Context objects.
    – mako-taco
    Commented Sep 20, 2013 at 17:26
  • Hi, @mako-taco, could you please give more hint?
    – Pylipala
    Commented Jun 4, 2015 at 2:51

Not the answer you're looking for? Browse other questions tagged or ask your own question.