让我们考虑一下这段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);
为什么行为不同?这真让我困惑。感谢。
答案 0 :(得分:52)
你的问题确实什么都没有与setTimeout
有关。您只需要了解函数调用和函数引用之间的区别。
考虑这四项任务:
var one = function() { mike.showName(); };
var two = mike.showName;
var three = mike.showName();
var four = (function() { mike.showName(); })();
前两个将函数的引用分配给它们各自的变量。然而,最后两个调用函数(这是parens的用途)并将它们的返回值分配给左侧的变量。
这与setTimeout的关系如何:
setTimeout
函数需要作为函数的第一个参数 reference ,因此上面的one
或two
都是正确的,但是{{1 }}和three
不会。但是,重要的是要注意,严格来说,错误并不是将函数的返回值传递给four
,尽管您经常会看到这样说。
这非常好,例如:
setTimeout
它与 function makeTimeoutFunc(param) {
return function() {
// does something with param
}
}
setTimeout(makeTimeoutFunc(), 5000);
如何接收函数作为其参数无关,而它接收。
答案 1 :(得分:19)
如果接受的答案太长而无法阅读:
setTimeout(mike.showName(), 5000);
这将在5,000毫秒后执行mike.showName()
返回。
setTimeout(function(){ mike.showName(); }, 5000);
这将在5000毫秒之后执行匿名函数,调用mike.showName()
,实际函数。
达到同样效果的另一种方法:
setTimeout(mike.showName.bind(mike), 5000);
答案 2 :(得分:9)
这不是性能问题。你展示的方法之一根本不起作用(它立即调用函数,而不是在超时触发时)。
setTimeout(mike.showName(), 5000);
将执行showName
函数并将其返回值设置为超时回调,这将无效。
setTimeout(function(){ mike.showName(); }, 5000);
创建一个匿名函数并将其设置为超时回调。当超时触发时,将调用该函数并调用showName()
函数。
Fyi,setTimeout('mike.showName();', 5000);
也会奏效。但不这样做 - 它与使用eval()
一样糟糕。除此之外,它使您的代码可读性降低,因为字符串中的代码不能以语法突出显示。
答案 3 :(得分:4)
setTimeout(mike.showName(), 5000);
立即执行mike.showName()
并将返回值传递给setTimeout()
setTimeout(function(){ mike.showName(); }, 5000);
传递指向函数的指针。那样setTimeout
可以执行函数,而不是它的返回值。