Does the Arguments object leak?

Assuming I had this function, which (for some odd reason) returns its arguments object to the caller:

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

Does storing the result of an invocation ( var d=example(); ) prevent the variable environment of example (containing a , b , c etc) from being garbage-collected? The internal setters and getters of the Arguments object might still refer to it, just like a function returned from a closure does.

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


Consider this:

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

It's false, because it's not the same arguments object: it's (for each invokation of x ) a newly constructed object that has the values of all the params stored within. Yet it has properties of arguments :

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; }

Yet there's more to this. Obviously, objects sent into function as its params will not be collected by GC if arguments are returned:

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

This is expected: after all, you can get the similar result by declaring some local object inside the function, assigning the value of the function's first parameter as its object '0' property, then returning this object. In both case the referred object will still be "in use", so no big deal, I suppose.

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 see, if you return arguments object and assign it to some variable, inside the function its callee.argument property points to the same set of data as arguments itself; that's, again, expected. But outside the function variable.callee.arguments is equal to null (not undefined).


Without having done any research into a particular JavaScript engine this is hard to answer conclusively. I would however argue that the relation between the arguments Object and the context created by example is the same as of any other local variable and its host context.

That is to say, storing the value does not require its context to be stored as well.

One caveat is the arguments.callee property which is a reference to the context (ie Function ) which a given arguments Object is bound to. This property however does not exist in strict mode and also has been deprecated.

Other than that I think it's safe to assume that returning and storing the arguments Object won't lead to a memory leak.

链接地址: http://www.djcxy.com/p/11504.html

上一篇: Xcode:如何正确构建静态库项目?

下一篇: 参数对象是否泄漏?