带/不带括号的Javascript函数调用

时间:2016-01-02 06:37:59

标签: javascript parameter-passing parentheses function-calls

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教程的解释。

6 个答案:

答案 0 :(得分:3)

setTimeout(foo, 2000)将函数foo和数字2000作为参数传递给setTimeoutsetTimeout(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)

foofoo()之间的基本区别如下:

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>