code_0:
(不用括号调用foo
)
function foo(){
console.log('hello world');
}
setTimeout(foo, 2000);
这就是code_0
的执行方式:
start -> wait for 2 seconds -> 'hello world' displayed -> end
code_1:
(用括号调用foo
)
function foo(){
console.log('hello world');
}
setTimeout(foo(), 2000);
这就是code_1
的执行方式:
start -> 'hello world' displayed immediately -> wait for 2 seconds -> end
当我用括号调用函数时,为什么程序的执行方式会有所不同?什么是潜在的机制?
很抱歉,如果这个问题太琐碎了。但我找不到任何针对初学者的javascript教程的解释。
答案 0 :(得分:3)
setTimeout(foo, 2000)
将函数foo
和数字2000
作为参数传递给setTimeout
。 setTimeout(foo(), 2000)
调用foo
并将其返回值和数字2000
传递给setTimeout
。
在第一个例子中,你根本没有调用函数,只是将它作为参数传递,就像任何其他值一样。
作为一个更简单的例子,只需记录它:
function foo() {
return 5;
}
console.log(foo); // console.log is passed a function and prints [Function]
console.log(foo()); // foo() is called and returns 5; console.log is passed 5
// and prints 5
答案 1 :(得分:2)
在第一个代码段中,函数foo
正在传递到超时。这意味着超时到期后2秒后会调用foo
。
在第二个代码段中,函数foo
被调用以决定传递给超时的内容。因此在设置超时之前调用foo
。由于foo()
不返回任何内容,因此超时到期时不会发生任何事情。
答案 2 :(得分:2)
在您的问题中,foo
是
function foo(){
console.log('hello world');
}
而foo()
是
console.log(hello world)
setTimeout()方法在指定的毫秒数后调用一个函数或计算一个表达式,并且该函数应该是它的第一个参数,在第一种情况下,你传递一个函数,这就是为什么行为是预期的,在第二种情况下,你传递console.log(...)
这不是一个函数,所以它首先执行foo()
并在控制台hello world
打印然后等待2秒,什么都不做,从而显示出奇怪的行为。
参见
typeof foo; // is function
typeof foo(); // prints hello world in console first and then says undefined.
答案 3 :(得分:2)
foo
和foo()
之间的基本区别如下:
function foo() {
alert("bar");
return "baz";
}
console.log(foo); // gives "function"
console.log(foo()); // gives "baz"
foo
是对函数体本身的引用,而foo()
执行函数。因此
setTimeout(foo(), 2000);
将返回值(" baz")传递给函数setTimeout
(这将导致错误)。 setTimeout
期望"可执行文件"作为第一个参数,所以你需要传入对现有函数的引用。
答案 4 :(得分:1)
这里的混乱点是你没有意识到这一点
foo
没有括号不调用函数...它只引用它。
foo
是对函数本身的引用。要调用函数(即实际执行其代码),请在末尾用括号引用它(例如foo()
)。在实际意义上,这意味着:
// references the function itself
// ...you could call one() now and it would run the function foo
var one = foo;
// runs/calls the function, and var two will then be whatever foo returns
var two = foo();
所以在第一个例子中你不是在调用函数。您正在将函数foo
传递给setTimeout
。然后,setTimeout
会在延迟后调用。
在第二个示例中,您立即调用 foo,并将foo
返回的任何内容传递给setTimeout(setTimeout无法执行任何操作,因为返回值可能不是另一个函数) 。因此,您的函数立即执行,然后在setTimeout
完成延迟后不会发生任何事情(除了可能有些错误)。
答案 5 :(得分:0)
这是一个简单的解决方案。您可以使用括号,并在需要时将数据传递给函数。
<script>
function foo(){alert("hello world")}
setTimeout(function() {foo()}, 2000)
</script>