为什么使用匿名函数而不是函数引用作为参数被认为是更好的做法?

时间:2013-07-30 16:12:49

标签: javascript parameters anonymous-function

像这样:

addEventHandler(document.getElementById('btnAdd'), "click", function() 
   { addNewItem(); }, false);

而不是:

addEventHandler(document.getElementById('btnAdd'), "click", addNewItem, false);

我知道这与javascript解释器的工作方式有关。但是如何?

3 个答案:

答案 0 :(得分:4)

使用命名函数允许:

  • 更短,更易读,行
  • 描述性名称
  • 在其他地方轻松重复使用该功能

传递除了调用单个其他函数之外什么也不做的匿名函数(根据你的例子)只是膨胀 - 内联函数表达式的详细程度虽然仍然有一个命名函数,但它是两个世界中最糟糕的。

答案 1 :(得分:2)

使用命名功能包括:

  • 更多代码
  • 全球空间的污染
  • 代码不太可读,因为该功能未在其他地方使用并不明显

因此,如果您不重用该函数,最好使用匿名函数而不是创建命名函数。

但是,如果你的代码正是你所展示的代码,那么匿名函数完全没有意义。什么是第二个代码的等效匿名等价物是

addEventHandler(document.getElementById('btnAdd'), "click", function() {
    // addNewItem implementation
}, false);

如果你已经有一个命名函数,例如因为你重用了它,那么就不要使用匿名函数来包装它。

答案 2 :(得分:1)

我将提供意见而不是声称这是最佳做法。我以前总是将对命名函数的引用作为参数传递,而我永远不会传递小包装器匿名函数。但是,我已经放弃了这个标准。现在我传入对命名函数的引用,当我不怀疑我的函数的签名有很多迭代时,当我怀疑我的函数签名上有迭代时,我传入包装器匿名函数。

我将使用此JS Fiddle来解释我以前的标准,现行标准,以及为什么我放弃了旧标准。总而言之,我从一些错误中了解到,传递包装的匿名函数可以更加重构,因为您必须显式地编码您传递给函数的参数。不过,两种模式都有它们的位置。

var btn = document.getElementById('btn');
var btn2 = document.getElementById('btn2');

//I previously tended to pass in function name references.  However, I recently moved towards
//passing in anonymous functions because I found that pattern to be a bit more refactor safe.
//More specifically, it is more refactor safe when you suspect the signature of our function
//will change.  If you never expect the function's signature to change, then I guess you shouldn't
//need to worry about passing in an anonymous function.

//Because of the way addEventListener uses addNewItem, addNewItem will always receive one 
//paramter: the event object.  Therefore, we are not using addNewItem correct.  It expects one
//argument that is message.  Previously, we were calling addNewItem correctly when it looked like
//addNewItemOld and expected zero arguments.  Click "Add message incorrect" to see the incorrect 
//behaviour
btn.addEventListener("click", addNewItem);

//Now I often to wrap my function calls in anonymous functions because I know exactly what arguments
//I'm passing into my function.  In this case I am explicitely not passing in a message.  Now, we are
//using the addNewItem function correctly
btn2.addEventListener("click", function(e) { addNewItem(); });

//This function has been refactored.  It used to look like addNewItemOld.  The way
//this function's signature has been refactored is particularly interesting.  It now
//has an optional paramter called message.
function addNewItem(message) {
    var span =document.createTextNode(message || "Now nodes have a default message"),
        workspace = document.getElementById("workspace");
    workspace.appendChild(span);
}

function addNewItemOld() {
    var span =document.createTextNode("Every node has the same message"),
        workspace = document.getElementById("workspace");
    workspace.appendChild(span);
}