匿名函数内部的Does函数(callbacks")在每次回调时在内存中被重新定义

Does functions inside anononymus functions ("callbacks") gets redefined in memory on each callback?

本文关键字:函数 内存 回调 定义 新定义 callbacks Does quot 内部      更新时间:2023-09-26

如果您在匿名函数中定义函数,例如将"callback"函数用作参数。以Array.prototype.forEach为例:

['one','two','three'].forEach (function(item) {
  function showValue(i) {
    console.log (i);
  }
  showValue(item);
});

函数showValue会被"重新定义"3次吗?

如果我们把代码写成这种形式:

function handleItem(item) {
  function showValue(i) {
    console.log (i);
  }
  showValue(item);
}
['one','two','three'].forEach (handleItem);

有区别吗?

这个变化呢:

var handleItem = (function(item) {
  function showValue(i) {
    console.log (i);
  }
  return function(item) {
    showValue(item);
  }
})();

['one','two','three'].forEach (handleItem);

我想这是一个更"合适"的闭包。
这有什么区别吗?

函数showValue会被"重新定义"3次吗?

理论上,是的。实际上,JavaScript引擎真的很聪明。如果按照上面所示的操作,引擎几乎肯定会完全优化函数,将其代码内联。如果函数更复杂,不适合内联,引擎仍然可能只编译一次函数,并在每次迭代时更改其上下文。

有区别吗?

只有一个小的:在迭代完成后,内存中仍然有handleItem函数。showItem没有变化。

这个变化呢?我想这是一个更"合适"的结尾。

在迭代完成后,您将拥有handleItem,并且所有迭代都将使用相同的showItem,在迭代完成后,它仍然存在。(旁注:var handleItem = (function(item) {中的item是误导性的,您不接受那里的item。)


你认为其中一个变体在某种程度上比其他变体"更好"吗?

对于我来说,给定问题中的代码,答案是"以上皆非"。而不是:

['one', 'two', 'three'].forEach(function(i) {
    console.log(i);
});

我不认为真的有一个普遍的案例答案。这完全取决于handleItemshowItem实际做什么,它们有多复杂,你是否要重用它们,showItem是否需要做特定于handleItem的特定调用的事情(除了项目不同),等等。