简体   繁体   中英

Why console.log doesn't work as an argument?

In javascript there is a callback, and functions are first-class objects right? so i can pass a function as an argument however if i pass console.log() it doesn't work why is that isn't it a function as well?

setTimeout(function(){console.log("hello")},5000);

this code is valid however

setTimeout(console.log("hello"),5000);

produces an error, why is that?

When you call console.log with some argument, the argument is printed to console and the function returns undefined .

So when you do:

setTimeout(console.log("hello"),5000);

"hello" will be printed, but what you're essentially doing is:

setTimeout(undefined, 5000);

In the other example (that works) you create a new function, but you do not call it. So you pass this new function to setTimeout , and that is why it works.

The reason that the following code

setTimeout(console.log("hello"),5000); 

fails is because console.log() is invoked directly inside the setTimeout parameter and it always returns undefined (more info: MDN Documentation on Console.log ). This means you are essentially running setTimeout(undefined,5000);

You need to provide a function declaration that is not invoked. If you wrap the code inside of a function declaration and do not invoke it, setTimeout will invoke it for you after the specified time lapses. This is why your first statement works, you provide a function declaration:

setTimeout(function(){console.log("hello")},5000);

If you had invoked the function you provided in the first parameter it would also return undefined and "hello" would be output immediately.

So if you provide a function declaration it will work:

setTimeout(()=>{console.log("hello")},5000);

Another way to use console.log directly without a function declaration is to bind it to a variable (more info: MDN Documentation on Function.prototype.bind ). An example using .bind prototype:

setTimeout(console.log.bind(null,"hello"),5000);

The code above binds "hello" to invocation of console.log. The first parameter is null in this example but it is the this context.

setTimeout also allows you to pass variables that you want the function to be invoked with. See MDN Documentation on setTimeout

For example to pass a variable:

setTimeout(console.log,5000,'hello');

In the above example you are telling setTimeout to invoke console.log in 5 seconds with the variable (in this case a sting) of 'hello'.

Invoking console.log('hello') will return undefined so you are not really passing it to setTimeout , It will print "hello" though but not inside a callback.
In most cases it wont throw an error (as you can see in the example below).

What you can do however is pass console.log (the function) and a 3rd argument the string "hello" in our case.

Running example with all 3 cases:

 setTimeout(console.log("hello"),500); setTimeout(function(){console.log("hello2")},500); setTimeout(console.log,500,"hello3"); 

它会产生一个错误,因为它会计算console.log(...) ,它的计算结果为undefined ,因此不是函数。

setTimeout accepts the function as a parameter, not the function call. console.log() is basically invoking the function/method but setTimeout requires the reference or more specifically called the callback.

In your example:-

setTimeout(function(){console.log("hello")},5000);

you can call it like

var callback = function(){console.log("hello")};
setTimeout(callback,5000);

The callback will be called by setTimeout later in future. I hope it clears everything.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM