For example, if we assume the following code:
var f = function() { return 'hello world' };
var x = 10;
var y = 314;
var g = function() {
var bu开发者_运维问答f = [], 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!
I found this discussion of V8 closure implementations enlightening. It sounds like the C++ object you're looking for is a Context.
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.
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.
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
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.
精彩评论