【问题标题】:setTimeout callback argumentsetTimeout 回调参数
【发布时间】:2016-09-09 05:40:52
【问题描述】:

让我们考虑这段 JavaScript:

function Person(name) {
    this.name = name;
}

Person.prototype.showName = function() {
    alert(this.name);
}


var mike = new Person("mike");
//mike.showName();  

window.name = "window"; 

我不明白

的行为有什么区别
setTimeout(mike.showName(), 5000);

setTimeout(function(){
    mike.showName();
}, 5000);

为什么行为不同?这真的让我很困惑。谢谢。

【问题讨论】:

  • 当他说“性能”时,我相当肯定 OP 的意思是“行为”。

标签: javascript


【解决方案1】:

您的问题与setTimeout 确实毫无关系。您只需要了解函数调用和函数引用之间的区别。

考虑这四个任务:

var one = function() { mike.showName(); };
var two = mike.showName;
var three = mike.showName();
var four = (function() { mike.showName(); })();

前两个将一个函数的引用分配给它们各自的变量。然而,最后两个调用函数(这就是括号的用途)并将它们的返回值分配给左侧的变量。

这与 setTimeout 有何关系:

setTimeout 函数的第一个参数是一个函数的引用,所以上面的onetwo 都是正确的,但threefour 不会.然而,重要的是要注意,严格来说,将函数的返回值传递给setTimeout 并不是一个错误,尽管你会经常看到这样的说法。

这很好,例如:

function makeTimeoutFunc(param) {
    return function() {
        // does something with param
    }
}

setTimeout(makeTimeoutFunc(), 5000);

这与 如何setTimeout 接收函数作为其参数无关,但 它确实

【讨论】:

  • 非常感谢。你的回答很棒。但是,我仍然有一个困惑。你能告诉我为什么在 'function(){ mike.showName()' 等待 5 秒时会先执行 'mike.showName()' 吗?再次感谢。
  • @jsnewman - 传递 mike.showName() 表示现在运行函数 showName 并将它返回的任何内容作为回调传递,以在 5 秒内执行(这没什么)。但是,传递function(){ mike.showName() }setTimeout 提供了一个匿名函数,可以在五秒后运行。五秒钟过去了,外包装函数被执行。它包含一行,是对showName的调用,当时执行。
【解决方案2】:

如果接受的答案太长而无法阅读:

setTimeout(mike.showName(), 5000);

这将在 5,000 毫秒后执行任何 mike.showName() 返回

setTimeout(function(){ mike.showName(); }, 5000);

这将在 5000 毫秒后执行匿名函数,调用 mike.showName()实际函数

实现同样效果的另一种方式:

setTimeout(mike.showName.bind(mike), 5000);

【讨论】:

    【解决方案3】:

    这不是性能问题。您展示的其中一种方法根本不起作用(它立即调用该函数,而不是在超时触发时)。

    setTimeout(mike.showName(), 5000); 将执行showName 函数并将其返回值设置为超时回调,这将不起作用。

    setTimeout(function(){ mike.showName(); }, 5000); 创建一个匿名函数并将其设置为超时回调。当超时触发时,该函数被调用并调用您的showName() 函数。

    仅供参考,setTimeout('mike.showName();', 5000); 也可以。但是不要这样做 - 这和使用 eval() 一样糟糕。除此之外,它还会降低代码的可读性,因为字符串中的代码无法以语法高亮显示。

    【讨论】:

    • 你能告诉我为什么 'mike.showName()' 会先执行,而 'function(){ mike.showName()' 等待它的时间吗?非常感谢。
    • 因为您实际上调用了该行中的函数。如果你将它包装在一个匿名函数中,或者只传递没有() 的函数,它不会被调用 - 函数本身会被传递。
    【解决方案4】:

    setTimeout(mike.showName(), 5000); 立即执行mike.showName() 并将返回值传递给setTimeout()

    setTimeout(function(){ mike.showName(); }, 5000); 传递一个指向函数的指针。这样setTimeout 可以执行函数,而不是返回值。

    【讨论】:

      猜你喜欢
      • 2015-07-16
      • 2010-11-14
      • 1970-01-01
      • 1970-01-01
      • 2012-01-15
      相关资源
      最近更新 更多