Does the Arguments object leak?

Assuming I have this function that (for some odd reason) returns its arguments object to the caller:

 function example(a, b/* ...*/) { var c = // some processing return arguments; } 

Does the result of the call ( var d=example(); ) save the environment variable example (containing a , b , c , etc.) from garbage collection? The internal setters and getters of an object Arguments can still refer to it as a function returned from a closure.

I know that a use case is hardly used (and passing Arguments objects is considered bad practice, most likely due to their similarity with arrays), but this is more of a theoretical question. How do different implementations of EcmaScript handle this?

+7
source share
2 answers

Consider this:

 var x = function() { return arguments; } console.log( x() === x() ); 

This is false because it is not the same arguments object: it (for each involution x ) is a new object that has the values โ€‹โ€‹of all parameters stored inside. However, it does have arguments properties:

 var y = x([]); console.log(y instanceof Object); // true console.log(y instanceof Array); // false console.log(y.length); // 1 console.log(y.callee + ''); // function() { return arguments; } 

And yet there is more to it. Obviously, objects sent to the function as their parameters will not be collected by the GC if arguments returned:

 var z = x({some: 'value'}); console.log(z[0]); // {some:'value'} 

Expected: in the end, you can get a similar result by declaring some local object inside the function, assigning the value of the first parameter of the function as a property of the object "0", and then returning this object. In both cases, the mentioned object will still be "used", so I do not assume.

But what about this?

 var globalArgs; var returnArguments = function() { var localArgs = arguments; console.log('Local arguments: '); console.log(localArgs.callee.arguments); if (globalArgs) { // not the first run console.log('Global arguments inside function: '); console.log(globalArgs.callee.arguments); } return arguments; } globalArgs = returnArguments('foo'); console.log('Global arguments outside function #1: '); console.log(globalArgs.callee.arguments); globalArgs = returnArguments('bar'); console.log('Global arguments outside function #2: '); console.log(globalArgs.callee.arguments); 

Output:

 Local arguments: ["foo"] Global arguments outside function #1: null Local arguments: ["bar"] Global arguments inside function: ["bar"] Global arguments outside function #2: null 

As you can see, if you return the arguments object and assign it to some variable, inside the function its callee.argument property points to the same data set as arguments ; this, again, was expected. But outside the function variable.callee.arguments is zero (not undefined).

+3
source

Without any research into a particular JavaScript engine, this is hard to answer definitively. However, I argued that the relationship between the arguments Object and the context created by example is the same as for any other local variable and its host context.

That is, preserving a value does not require preserving its context.

One caveat is the arguments.callee property, which is a reference to the context (i.e., Function ) to which this arguments Object is bound. However, this property does not exist in strict mode, but is deprecated .

In addition, I find it safe to assume that returning and saving arguments Object will not result in a memory leak.

0
source

All Articles