匿名函数 ("callbacks") 中的函数是否在每次回调时在内存中重新定义?

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

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

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

函数showValue会"redefined" 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);

我猜这是一个更 "proper" 的闭包。
这会有什么不同吗?

Will the function showValue be "redefined" 3 times?

理论上是的。实际上,JavaScript 引擎 非常聪明 。如果你真的按照你所展示的去做,引擎几乎肯定会完全优化函数,内联它的代码。如果函数更复杂且不适合内联,引擎仍可能会编译函数一次,并在每次迭代时更改其上下文。

Is there a difference? memory-wise or otherwise.

只有一小部分:迭代完成后,内存中仍会有 handleItem 函数。就 showItem 而言,没有任何变化。

What about this variation? Which I guess is a more "proper" closure.

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


Do you think one of the variations is "better" somehow than the rest?

对我来说,给出问题中的代码,答案是 "none of the above." 而不是:

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

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