Javascript 函数调用 with/without 括号
Javascript function call with/without parentheses
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 初学者教程的解释。
setTimeout(foo, 2000)
将函数 foo
和数字 2000
作为参数传递给 setTimeout
。 setTimeout(foo(), 2000)
调用 foo
并将其 return 值和数字 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
在第一个代码片段中,函数 foo
被 传递给超时 。这意味着 foo
在超时到期 2 秒后被调用。
在第二个代码片段中,函数 foo
被调用 以决定将什么传递给超时 。所以 foo
在设置超时之前被调用。由于 foo()
没有 return 任何东西,超时到期时什么也不会发生。
在你的问题中,foo
是
function foo(){
console.log('hello world');
}
而 foo()
是
console.log(hello world)
setTimeout() 方法在指定的毫秒数后调用一个函数或计算一个表达式,这个函数应该是它的第一个参数,在你的第一个如果您传递的是一个函数,这就是预期行为的原因,而在第二种情况下,您传递的 console.log(...)
不是函数,因此它首先执行 foo()
并在控制台 [=16= 中打印] 然后等待 2 秒,什么也不做,因此表现出奇怪的行为。
参见
typeof foo; // is function
typeof foo(); // prints hello world in console first and then says undefined.
foo
和 foo()
的基本区别如下:
function foo() {
alert("bar");
return "baz";
}
console.log(foo); // gives "function"
console.log(foo()); // gives "baz"
foo
是对函数体本身的引用,而 foo()
执行 函数。于是
setTimeout(foo(), 2000);
将 return 值 ("baz") 传递给函数 setTimeout
(这将导致错误)。 setTimeout
需要一个 "executable" 函数作为第一个参数,因此您需要传入对现有函数的引用。
The point of confusion here is that you're not realizing that using
foo
without parentheses is not calling the function...it's only referencing it.
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
returns 传递给 setTimeout(setTimeout 无法对其执行任何操作,因为return 值可能不是另一个函数)。所以你的函数被立即执行,然后在 setTimeout
完成它的延迟之后什么都不会发生(除了可能的一些错误)。
这是一个简单的解决方案。如果需要,您可以使用括号并将数据传递给函数。
<script>
function foo(){alert("hello world")}
setTimeout(function() {foo()}, 2000)
</script>
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 初学者教程的解释。
setTimeout(foo, 2000)
将函数 foo
和数字 2000
作为参数传递给 setTimeout
。 setTimeout(foo(), 2000)
调用 foo
并将其 return 值和数字 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
在第一个代码片段中,函数 foo
被 传递给超时 。这意味着 foo
在超时到期 2 秒后被调用。
在第二个代码片段中,函数 foo
被调用 以决定将什么传递给超时 。所以 foo
在设置超时之前被调用。由于 foo()
没有 return 任何东西,超时到期时什么也不会发生。
在你的问题中,foo
是
function foo(){
console.log('hello world');
}
而 foo()
是
console.log(hello world)
setTimeout() 方法在指定的毫秒数后调用一个函数或计算一个表达式,这个函数应该是它的第一个参数,在你的第一个如果您传递的是一个函数,这就是预期行为的原因,而在第二种情况下,您传递的 console.log(...)
不是函数,因此它首先执行 foo()
并在控制台 [=16= 中打印] 然后等待 2 秒,什么也不做,因此表现出奇怪的行为。
参见
typeof foo; // is function
typeof foo(); // prints hello world in console first and then says undefined.
foo
和 foo()
的基本区别如下:
function foo() {
alert("bar");
return "baz";
}
console.log(foo); // gives "function"
console.log(foo()); // gives "baz"
foo
是对函数体本身的引用,而 foo()
执行 函数。于是
setTimeout(foo(), 2000);
将 return 值 ("baz") 传递给函数 setTimeout
(这将导致错误)。 setTimeout
需要一个 "executable" 函数作为第一个参数,因此您需要传入对现有函数的引用。
The point of confusion here is that you're not realizing that using
foo
without parentheses is not calling the function...it's only referencing it.
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
returns 传递给 setTimeout(setTimeout 无法对其执行任何操作,因为return 值可能不是另一个函数)。所以你的函数被立即执行,然后在 setTimeout
完成它的延迟之后什么都不会发生(除了可能的一些错误)。
这是一个简单的解决方案。如果需要,您可以使用括号并将数据传递给函数。
<script>
function foo(){alert("hello world")}
setTimeout(function() {foo()}, 2000)
</script>