"arguments" 对象会阻止未绑定参数的垃圾回收吗?

Will the "arguments" object prevent garbage collection for unbound arguments?

如果我有一个函数 sum “接受”两个参数,那么 returns 一个将在“很长”时间内解决的承诺。传递给 sum 的任何参数(超过前两个参数)是否会保留在内存中,并且不会被垃圾收集?

例如,sum 会阻止“大对象”FOO 被垃圾收集吗?

const sum = (a, b) => new Promise((resolve) => {
  setTimeout(() => resolve(a+b), 500 /* Lets pretend this is a huge number */);
});

(async () => {
  const s = await sum(2, 3, {/* Some large object, FOO */});
  console.log(s);
})();

我假设因为您可以通过“arguments”对象访问 FOO,那么 FOO 需要保存在内存中吗?但是,由于“参数”在箭头函数中不可访问,因此关键字函数和箭头函数之间的这种行为会有所不同吗?

function sum(a, b) {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(...arguments);
      resolve(a+b);
    }, 500 /* Lets pretend this is a huge number */);
  });
};

const arrowSum = (a, b) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(...arguments);
      resolve(a+b);
    }, 500 /* Lets pretend this is a huge number */);
  });
};

(async () => {
  const s = await sum(2, 3, {/* Some large object, FOO */});
  console.log(s);
  
  const arrowS = await arrowSum(2, 3, {/* Some large object, FOO */});
  console.log(arrowS);
})();

来自 twitter thread with Surma(google 工程师)。

问:“arguments”对象会阻止未绑定参数的垃圾回收吗?
A: 是的,很有可能。您可以通过 eval() 访问 arguments,因此 engine/compiler 永远无法证明您不会访问它并释放该对象。

Q: 由于“arguments”在箭头函数中不起作用,那么从消费者滥用不会导致与关键字函数一样糟糕的性能?
A: 理论上,我猜箭头函数会在此处进行优化,而普通函数不会。