function functionOne(x){console.log(x);};
function functionTwo(var1) {
};
functionTwo(functionOne(2));
why does functionTwo work there ? it doesn't suppose work, does it?
because there is not an operation.
functionTwo(functionOne(2));
This means "immediately call functionOne, passing in 2. Then pass the result into functionTwo". So functionOne does its thing, logging out 2, and then returns undefined. And then undefined is passed into functionTwo.
Instead, if you're trying to experiment with callbacks you need to pass a function in, as in:
functionTwo(() => functionOne(2));
Once you do that, you'll no longer see a console.log unless you add some code to functionTwo.
Related
I have the following function
function hello() {
alert("hi!");
}
Take this piece of code:
var elem = document.getElementById("btn");
elem.onclick = hello;
My question might be a bit hard to understand, so bear with me:
What EXACTLY differentiates THIS piece of code from a normal call, or what makes this piece of code require a reference to the function variable rather than a regular call? (hello();)
How can I know where I'm supposed to give a reference to the function, and when I'm supposed to actually call it?
Well, the onclick property expects a reference to a function, for it to execute when the element is clicked. Normally it's either:
element.onclick = funcRef;
or
element.onclick = function () {
funcRef();
};
(but of course, it's best to use addEventListener and attachEvent)
Notice how both of them are references to functions, not calling.
When something expects a reference, you don't call it...you assign a reference to it (first example).
When you want to specifically call a function, you call it with () (second example). But notice how in the second example, there's still a reference to a function that's assigned to onclick - it's just an anonymous function.
Probably the more important part:
Some people think you want to do this:
element.onclick = funcRef();
But that immediately executes the function (because of the ()), and assigns its return value to onclick. Unless the return value is a function, this isn't what you want.
I think the moral of the story is that when you want/need something to execute right now, you call the function. If the function is wanted for later use or needs stored, you don't call it.
Do you want it to execute NOW? Then call it.
a=hello() means "Call hello() ASAP, and set its return value to a".
On the other hand, a=hello means "a is an alias for hello. If you call a(), you get the same results as calling hello()"
You use the latter for callbacks, etc, where you want to tell the browser what you want to happen after an event occurs. For example, you may want to say "call hello() when the user clicks" (as in the example). Or, "When the AJAX query returns a result, call the callback() function on the returned data".
How can I know where I'm supposed to give a reference to the function, and when I'm supposed to actually call it?
Do you need the function to run now?
Than add the () to execute it
Do you need to function to be referenced so it is called later?
Do not add the ().
Pretty much all statements in JavaScript have a return value. Unless otherwise specified, functions in JavaScript will return undefined when called. So, the only context in which it would make sense to call your function in this assignment statement if it were to return a function:
function hello() {
return function() {
alert("hi!");
}
}
elem.onclick = hello();
A reference to your function is needed somewhere no matter how it gets called. The difference here is that you are not explicitly calling the hello function. You are assigning a reference to that function to the elem DOM node's onclick event handler so that when onclick is fired for that Node, your function gets called.
hello() means you call that function, which means the function will be executed directly.
while when you have elem.onclick = hello, this is called a callback. Where hello doesn't get executed directly but only when a certain event is fired (in this case when there's a click on the element)
This question already has answers here:
What is the difference between a function call and function reference?
(6 answers)
Closed 12 months ago.
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");
It produces an error since it evaluates console.log(...), which evaluates to undefined, and thus is not a function.
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.
I have the following function
function hello() {
alert("hi!");
}
Take this piece of code:
var elem = document.getElementById("btn");
elem.onclick = hello;
My question might be a bit hard to understand, so bear with me:
What EXACTLY differentiates THIS piece of code from a normal call, or what makes this piece of code require a reference to the function variable rather than a regular call? (hello();)
How can I know where I'm supposed to give a reference to the function, and when I'm supposed to actually call it?
Well, the onclick property expects a reference to a function, for it to execute when the element is clicked. Normally it's either:
element.onclick = funcRef;
or
element.onclick = function () {
funcRef();
};
(but of course, it's best to use addEventListener and attachEvent)
Notice how both of them are references to functions, not calling.
When something expects a reference, you don't call it...you assign a reference to it (first example).
When you want to specifically call a function, you call it with () (second example). But notice how in the second example, there's still a reference to a function that's assigned to onclick - it's just an anonymous function.
Probably the more important part:
Some people think you want to do this:
element.onclick = funcRef();
But that immediately executes the function (because of the ()), and assigns its return value to onclick. Unless the return value is a function, this isn't what you want.
I think the moral of the story is that when you want/need something to execute right now, you call the function. If the function is wanted for later use or needs stored, you don't call it.
Do you want it to execute NOW? Then call it.
a=hello() means "Call hello() ASAP, and set its return value to a".
On the other hand, a=hello means "a is an alias for hello. If you call a(), you get the same results as calling hello()"
You use the latter for callbacks, etc, where you want to tell the browser what you want to happen after an event occurs. For example, you may want to say "call hello() when the user clicks" (as in the example). Or, "When the AJAX query returns a result, call the callback() function on the returned data".
How can I know where I'm supposed to give a reference to the function, and when I'm supposed to actually call it?
Do you need the function to run now?
Than add the () to execute it
Do you need to function to be referenced so it is called later?
Do not add the ().
Pretty much all statements in JavaScript have a return value. Unless otherwise specified, functions in JavaScript will return undefined when called. So, the only context in which it would make sense to call your function in this assignment statement if it were to return a function:
function hello() {
return function() {
alert("hi!");
}
}
elem.onclick = hello();
A reference to your function is needed somewhere no matter how it gets called. The difference here is that you are not explicitly calling the hello function. You are assigning a reference to that function to the elem DOM node's onclick event handler so that when onclick is fired for that Node, your function gets called.
hello() means you call that function, which means the function will be executed directly.
while when you have elem.onclick = hello, this is called a callback. Where hello doesn't get executed directly but only when a certain event is fired (in this case when there's a click on the element)
How could I call a function, then when it's done, call another function passing the first function's return value as parameter? I read a lot about Deferred but can't figure out how it works.
https://api.jquery.com/category/deferred-object/
https://api.jquery.com/jQuery.Deferred/ and so on mainly on SO..
Here's some sample:
function a() {
new amodel.AModel().save(vm.elem).done(function(_elem) {
vm.elem(_elem);
}).fail(function(error) {
...
});
function b(param) {
...
} //should call this with the a() return value
I tried to make it work as the follow:
$.when(a()).then(b());
This way I can't pass a parameter on, and I'm not even sure if it does what I would like to.
UPDATE:
Sorry, I wrote it wrong. I don't have to pass the return value as parameter, since when function a runs and gets done, it sets the value (vm.elem(_elem)) which will be used for an ajax call's parameter in function b.
If a returned a promise, then it will automagically pass the result on to b when chaining together using then
Therefore what you want is a().then(b).
Note that b is not passed with parentheses, that would pass the result of calling b to the chain. What you actually are doing is passing a reference to b into the chain and say "Call b when you have resolved the result of a".
Here is a live example which demonstrates: http://jsfiddle.net/9wvb1d2a/
im learning javascript, and i have been following some video tutorial on youtube
this is the original code
function add(first, second, callback){
console.log(first+second);
callback();
}
function logDone(){
console.log("done");
}
add(2,3,logDone);
and the result of code on above is
5
main.js (line 4)
done
main.js (line 9)
and i make slight change to the code into this
function add(first, second, callback){
console.log(first+second);
callback;
}
function logDone(){
console.log("done");
}
add(2,3,logDone());
and the result is this
done
main.js (line 9)
5
main.js (line 4)
my question are:
could you explain to me why i got the result pile up that way?,
and what the difference if we call a function with the bracket () and without the bracket ()?
Explanation of the first snippet
function add(first, second, callback) {
console.log(first + second);
callback(); // run whatever the "callback" function is
}
function logDone() {
console.log("done");
}
add(2, 3, logDone); // pass in a function (not an invocation of a function) the
// function isn't run here
Explanation of the second snippet
function add(first, second, callback) {
console.log(first + second);
callback; // display the value of whatever "callback" is
}
function logDone() {
console.log("done");
}
add(2, 3, logDone()); // run "logDone" and then pass the result (which in this
// case is undefined) into add
As you can see, the first code snippet doesn't actually run the callback until in the add function, whereas the second snippet runs the callback before add so that it can pass whatever comes back from logDone into add.
Perhaps it becomes more clear to you when I alter the logDone declaration to this:
var logDone = function() {
console.log("done");
}
The identifier logDone basically is just a variable that references a function. To execute (also: call, or: invoke) the function you add parentheses: logDone().
So, in your first example you are merely passing the function itself as the third argument to add(), which then gets executed inside add(), with callback();.
In your second example, however, you are executing the function with logDone() immediately, which results in the return value of logDone()1 being passed as the third argument to the add() call. In other words, first logDone is executed (resulting in the first log message), then add is executed (resulting in the second log message).
Furthermore, the statement callback;, inside add, does not do anything. And if you would have left the parentheses just like in your first example, it would result in an error, because undefined2 is not a function.
1) which is undefined in this case, because logDone() does not explicitly return anything.
2) the value that was the result of the logDone() call.
and what the difference if we call a function with the bracket () and without the bracket ()?
If you have () then you call it. If you don't, then you don't.
could you explain to me why i got the result pile up that way?,
In the first example you pass a function to add and then the add function calls it.
In the second example, you call the function and pass its return value (undefined) to add which then mentions it in a statement but doesn't do anything with it.
When you do func([args=optional]), func is getting invocated or called.
and what the difference if we call a function with the bracket () and
without the bracket ()?
We call the function only when we do ()(arguments optional). When a function is without parenthesis, you're just using it's reference.
By storing a reference do a function in a variable, you can call it later, that's what callback is doing.
In the second snippet, since nothing is returned, callback will have undefined. Try calling it by doing callback() in the second snippet, and you should see an error stating,
undefined is not a function.
In the first example, you are passing a function as a parameter.
In your second example, you are passing a functions result after invocation as a parameter.