setTimeout传递了命名函数与匿名函数

时间:2014-01-03 19:38:13

标签: javascript

MDN page for window.setTimeout上我找到了一个将命名函数传递给window.setTimeout的示例:

var timeoutID;

function delayedAlert() {
  timeoutID = window.setTimeout(slowAlert, 2000);
}

function slowAlert() {
  alert("That was really slow!");
}

function clearAlert() {
  window.clearTimeout(timeoutID);
}

在我维护的代码中,我遇到了这个示例的等价物,其中声明了匿名函数,因为它被传递给window.setTimeout

var timeoutID;

function delayedAlert() {
  timeoutID = window.setTimeout(function(){
    alert("That was really slow!");
  }, 2000);
}

function clearAlert() {
  window.clearTimeout(timeoutID);
}

这两种延迟警报的方法之间是否有重要区别?我更信任MDN而不是我正在使用的代码,所以我想理解为什么MDN使用单独的函数声明来表达他们的示例。

编辑:感谢@TravisJ @jfriend00 @PlatinumAzure提供清晰有用的答案。

3 个答案:

答案 0 :(得分:7)

如果没有做太多,那就没有什么区别了。匿名函数将使用比单独函数少得多的内存量。

原因是单独的函数声明将基本上用作指针,因此可以重复使用。但是,每次都需要构建匿名函数。这是一个非常小的差异。

基本的区别在于范围和参数。您不能将参数传递给函数指针。超时内的函数是否需要与其父级共享范围?如果是这样,那么匿名函数可能比另一个范围中的声明函数更有价值。一个常见的方法是传入this

var that = this;
window.setTimeout(function(){
 //keep in mind this anonymous function's `this` will be window
 showAlert(that.message);
},2000;

为了传递消息,例如,如果您的提醒是function showAlert(msg),那么您需要使用匿名函数window.setTimeout(function(){showAlert("hello");}, 2000);

你真正想避免使用的是那里的一个字符串。如

window.setTimeout("slowAlert()", 2000);

这被认为是不好的做法,因为函数将基于类似于使用eval的字符串构建。

答案 1 :(得分:3)

使用内联匿名函数与单独声明的命名函数之间没有任何功能差异。两者都会完全相同。

匿名函数的优点:

  1. 在您运行的任何命名空间中都没有使用符号名称。如果这是全局命名空间,则不污染全局命名空间或冒第三方库或其他开发人员发生命名冲突的风险非常重要。该项目。
  2. 代码是内联本地可读的 - 读者不必去找那个命名函数来查看回调应该发生什么。
  3. 内联函数可以访问当前作用域中的变量(偶尔非常有用)。
  4. 命名函数的优点:

    1. 可以单独调用命名函数用于其他用途(如果有用)。
    2. 在深度嵌套函数或实际函数很长的某些情况下,如果不对内联进行内联以保持实现的长度不会干扰周围代码的可读性,则可能更具可读性。
    3. 仅供参考,如果需要,内联声明的函数也可以有一个名称,这样两种形式也可以混合使用。


      我个人的选择是使用内联匿名函数,除非有明确的某些原因,我选择这个是为了上面提到的匿名函数的优点。

答案 2 :(得分:2)

这两种方法都有效,并且功能相同。

我的建议是使用命名函数,如果该函数很长并且如果内联呈现则会导致代码难以读取,并且对于快速单行使用内联匿名函数。但老实说,这取决于你。