参数对象是否泄漏?

假设我有这个函数,哪个(出于某种奇怪的原因)将其arguments对象返回给调用者:

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

存储调用结果( var d=example(); )是否阻止example (包含abc等)的变量环境被垃圾收集? Arguments对象的内部设置器和getter可能仍然引用它,就像从闭包返回的函数一样。

我知道几乎没有用例(并且传递参数对象被认为是不好的做法,很可能是因为它们与数组相似),但这更多是一个理论问题。 不同的EcmaScript实现如何处理这个问题?


考虑这个:

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

它是错误的,因为它不是相同的arguments object:它是(对于每个x调用)一个新构造的对象,它具有存储在其中的所有参数的值。 然而它具有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; }

但还有更多。 显然,如果返回arguments ,那么作为参数发送到函数的对象将不会被GC收集:

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

这是预料之中的:毕竟,通过在函数中声明一些本地对象,将函数的第一个参数的值指定为其对象的'0'属性,然后返回该对象,可以得到相似的结果。 在这两种情况下,所提到的对象仍然是“正在使用”,所以没有什么大不了的,我想。

但是这个怎么样?

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

输出:

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

正如你所看到的,如果你返回arguments对象并将它赋给某个变量,那么在函数内部它的callee.argument属性指向与arguments本身相同的一组数据; 这也是预期的。 但在函数variable.callee.arguments之外等于null(而不是未定义)。


如果没有对某个特定的JavaScript引擎进行任何研究,这很难得出确凿的答案。 然而,我会争辩说, arguments Objectexample创建的上下文之间的关系与任何其他局部变量及其主机上下文相同。

也就是说,存储该值并不需要存储它的上下文。

一个警告是arguments.callee属性,它是对给定arguments Object绑定的上下文(即Function )的引用。 但是,该属性在严格模式下不存在,并且已被弃用。

除此之外,我认为可以肯定的是,返回并存储arguments Object不会导致内存泄漏。

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

上一篇: Does the Arguments object leak?

下一篇: Where to put data access code?