首页 > 解决方案 > “参数”对象会阻止未绑定参数的垃圾收集吗?

问题描述

如果我有一个sum“接受”两个参数的函数,则返回一个将在“长时间”内解决的承诺。传递给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);
})();

我假设因为您可以通过“参数”对象访问 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);
})();

标签: javascriptgarbage-collectionarguments

解决方案


来自Surma(谷歌工程师)的推特线程。

问: “参数”对象会阻止未绑定参数的垃圾收集吗?
答:是的,很有可能。您可以arguments通过 eval() 访问,因此引擎/编译器永远无法证明您不会访问它并放开对象。

问:既然“参数”在箭头函数中不起作用,那么从消费者滥用不会导致像关键字函数那样糟糕的性能的意义上说,这是否会使箭头函数更具性能?
A:理论上,我猜箭头函数在这里会有一个普通函数没有的优化。


推荐阅读