考虑一下:
var x = function() {
return arguments;
}
console.log(x() === x());
这是假的,因为它是不一样的arguments
对象:它的(对于x
每个invokation)一个新构造的对象具有值存储中的所有PARAMS的。然而,它的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; }
然而,有更多的这一点。显然,物体送入功能作为其PARAMS不会被GC回收,如果arguments
返回:
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(不是undefined)。
关于'arguments'的奇怪之处在于,命名参数实际上是**数组**,用于伪数组的元素。尝试一下!如果你改变'arguments [0]',那么'a'也会改变!我不认为它出于这个原因泄漏。 – Pointy
真的吗?我认为这是另一种方式:'arguments [0]'是'a'的别名:-)规范中描述的算法表明'arguments'的索引是带有“ParameterMap”的setter&getters和链接到调用的环境记录 - 可能泄漏imho的原因。这就是为什么我也在问实际的实现... – Bergi
嗯,我想这是一种神秘的 - 这是一个别名为:-)我在想的是因为参数对象基本**是**它不需要对闭包或任何东西的引用,所以除了它直接使用的内存以外,它不会“钉住”任何其他东西。然而,这只是一种预感,我不知道真实的故事。 – Pointy