Do I have an accurate understanding of callback functions? - javascript

I've been a Javascript tinkerer for quite some time and recently I have been trying to have a real good understanding of the code I write. I want to get really good at writing Javascript. One of the things that's confused me a little bit was the usage of callback functions. I've just avoided using callbacks up until now. Right now, I'd like to know if my understanding of how a basic callback works is accurate and also if my understanding of parameters and arguments is accurate and finally, what the purpose is of using the callback in this scenario. Is there a benefit to using the callback function I've created below? If not, when are callback functions most beneficial? I realize what I've written below is quite lengthy so for the TLDR people: Am I right in thinking It's as if I created the function "theCallback" within "myFunction"? If so, what is the benefit in the scenario below? Why not just call a function? why must the function being called be an argument in the "myFunction" function?
If the scenario below doesn't make it necessary for using a callback, when is it necessary and what are the benefits? Thanks.
Here's how I see the code below: I've created a factory function "myFunction" with two parameters "x" and "callback" and parameters are pretty much variables that will be stored with arguments when the function is called. I also created another factory function "theCallback" with two parameters "x" and "theValue". Now since these are factory functions, regardless of them being underneath a function call to "myFunction", they will be hoisted above the function call so there are no problems. Had I created a function expression with a variable, they would not be hoisted. So now my call to "myFunction" has two arguments that the parameters in it will be defined as, "3" and "theCallback". The "theCallback" argument is a function. This function has the two parameters "x" and "theValue". When "myFunction" is called, "x" is stored with the argument "3" and "callback" is stored with the function "theCallback" and then the code within "myFunction" is executed which is simply a variable declared and assigned a value of a string that contains the text "for the callback" and the callback variable (I'm viewing as a variable), which was a parameter that is now an argument which is "theCallback" function I created which also contains parameters itself, is called, and given arguments for it's code to execute. In this case, the code it will execute calls the built in alert function (or method of the window object?) and gives the alert function a string argument, followed by the
alert function called again with the argument of "x" which is stored with "3" and then again alert is called and given the argument of "theValue" which contains the string "for the callback". Now when "theCallback" function is passed as a second argument to "myFunction" and it's stored in "callback", It's as if I created the function "theCallback" within "myFunction" right? If so, what is the benefit in the scenario below? Why not just call a function, why must the function being called be an argument in the "myFunction" function?
If the scenario below doesn't make it necessary for using a callback, when is it necessary and what are the benefits?
myFunction(3, theCallback);
function myFunction(x, callback){
var value = 'for the callback';
callback(x, value);
}
function theCallback(x, theValue){
alert('this is the callback function');
alert(x);
alert(theValue);
}

Is there a benefit to using the callback function I've created below?
That's a little subjective. Using a callback is unnecessary there. Normally you would return data from one function and pass it to the other.
when are callback functions most beneficial?
When you need to deal with the data after an event has fired, instead of immediately. e.g. when a button is clicked or an HTTP response has fired.
myButton.addEventListener("click", myCallbackFunction);
I've created a factory function "myFunction"
No. That is just a function. Factory functions create class objects.
they will be hoisted
Function declarations (as opposed to function expressions) are hoisted. This isn't relevant to callbacks though. A callback is basically a function passed as an argument, it doesn't matter how it was created.
what are the benefits
The benefits are that you can have different things happen when the event fires depending on the circumstance.
Take the click event example above. Often you'll want clicking on different things to have different effects, not the one thing that addEventListener was hardcoded to make happen by the browser vendor.

Related

Do number of input parameters in a callback function matter?

I'm learning Java Script at the moment via a course on Udemy, and I stumbled something I found peculiar.
It is about "callback functions" and the implementation in the course uses anonymous functions.
For example
var button = document.querySelector("button");
button.addEventListener("click", function() { console.log("hi"); } );
document.addEventListener("keydown", function(event) { console.log(event); } );
In the second line, the callback function is an anonymous function with no input parameters. In the third line, the anonymous function has one input parameter: event.
I feel like we are assuming that the callback can handle 0 or 1 input parameters, but how can we know for certain? What if I define an anonymous function with 3 input parameters? Would it matter?
Both lines will work, so I'm really surprised in the flexibility of the callback function.
It's not a feature of callback parameters. It's how functions behave in general in javascript.
A function defined with one parameter can be called with either zero, one or more than one parameter in javascript without any syntax errors:
function testing (a) {
console.log(a);
}
testing(); // will log undefined
testing('hello'); // logs "hello"
testing('hello', 'world'); // logs "hello"
This means:
A function with zero parameters may be called with any number of arguments
A function with many parameters may be called with no arguments
DOM events will always call your function with one argument (except on older versions of IE which will call them with zero arguments):
your_callback(event);
As such, you are free to define your callback with an argument if you plan to use it or omit the argument if you want to ignore it.

JavaScript: setting to the callback or the anonymous function

MY ISSUE
I've been learning the basics of AJAX from two different internet sources. In the multi-step process of sending an async HTTP request, there's one small inconsistency in how the .onload property is called on the XHR request object and then set to 1) an anonymous function or 2) a callback (??? that's what I think MDN says).
1ST APPROACH
the .onload property is called on the ourRequest object and this is set to an anonymous function:
ourRequest.onload = function() {
// the code goes here
}
2ND APPROACH
the .onload property is called on the asyncRequestObject object and this is set to the name of the function (a callback??):
function handleSuccess () {
// the code goes here
}
asyncRequestObject.onload = handleSuccess;
MY QUESTION(S)
What's the difference between how the 1st and the 2nd approach work?
And then, is there any reason to use the 1st approach over the 2nd approach?
A function declaration creates a (hoisted) variable in the current scope, that has the same name as the function, and whose value is a reference to that function.
A function expression simply evaluates as a reference to that function.
So the primary difference is that where you use handleSuccess, you can continue to reference the function for other purposes elsewhere.
What's the difference between how the 1st and the 2nd approach work?
The difference is that the first function is an anonymous function expression while the second is a function with a name. Both are event handlers for the "load" event of the XMLHttpRequest .
And then, is there any reason to use the 1st approach over the 2nd approach?
If you don't plan to reuse your handler somewhere else then you don't need to declare your function with a name.
It is no different than any other programming practice. Use a variable/constant when a value is called multiple times, otherwise use a literal.

Difference between passing a callback versus a function

I'm curious, is there any difference between the two functions below?
Is one just passing a function inside an anonymous function when ready whereas the other is passing an actual named function when ready?
Example:
<p>Not loaded yet.</p>
First method:
function newName() {
$( "p" ).text("The DOM is now loaded and can be manipulated.")
}
$(document).ready(function() {
newName()
});
Second method:
function newName() {
$( "p" ).text( "The DOM is now loaded and can be manipulated.")
}
$(document).ready(newName());
Is one more correct than the other?
Is one just passing a function inside an anonymous function when ready whereas the other is passing an actual named function when ready?
Yes and no.
I'm curious, is there any difference between the two?
The first is passing an callback function that is executed when the event fires. When that even fires is explained here.
The latter passes the resolved return value (which is undefined because newName has no return statement), which isn't the same as the second. The reason it passes the return value to ready is because you invoke the function immediately (which may seem like it works), which then passes the return value. To make them functionally equivalent, do:
$(document).ready(newName);
This will pass a function reference, and won't invoke it. Also, as mentioned before, invoking as ready(func(); func2();) is not valid syntax.
Effectively there’s no difference between
$(document).ready(function(){
newName();
});
and
$(document).ready(newName);
There’s a small technical difference: in the first snippet, an anonymous function calling newName is passed, in the second snippet, the named function newName itself is passed.
Functions are just callable objects that can be referenced by their name or the name of a variable holding the function.
Note that $(document).ready(newName()); is calling newName — immediately — and passing the return value to ready. This only makes sense if newName returns another function, which in this case it doesn’t.
The title also mentions something like $(document).ready(newName){}. I’m assuming that’s a typo, since that’s not valid syntax.
$(document).ready(newName(); otherName(); otherName1()); also isn’t valid syntax.

JavaScript examples, clarify the langue pattern design for functions with-in functions

I am learning JavaScript and becoming confused by the logic of the code examples. From codecademy. Why are there function set-ups in function calls?
I'm quite confused. I am moving from a simplified C-like langue.
The JavaScript example
var main = function(){
$('.article').click(function(){
$('.description').hide();
$(this).children('.description').show();
});
};
My understanding:
- main is a function name with a return type of var.
$('.article') is a element/object/or class object.
.click() is a call to a member function
But:
???:
.click(function(){
$('.description').hide();
$(this).children('.description').show();
});
This seems to be a newly on the spot created function to run When/If click() is activated or run.
The way I used to think is like this:
var *p_obj = $('.article');
var *p_obj = $('.description');
var do_click()
{
p_obj2.hide();
p_obj.children(p_obj2).show();
}
var main(){
p_obj.click(do_click);
}
Function main() looks at p_obj and calls click().
Click() evaluates to true/false and run the pointer_to function do_click().
Function do_click() looks at the p_obj2 and calls hide(), which performs an action of hiding the p_obj2.
Function do_click() also looks at p_obj and uses children to scope focus to p_obj2, then it runs show(), which preforms an action of displaying p_obj2.
I do realize my C-like example is wrong and odd. I realize my terminology is wrong or otherwise used incorrectly.
The way this design looks seems like I must write extended functionality on-the-spot for every call to .click(), so if-then .click() is run on 3 different items, I'm creating different extended functionality for each object. But I would normally create a single function that varies it's internal execution based on the object or condition click() calls it by.
This set-up seems alright if the code a relatively simple or short, but on-the-spot functional seems like overworking for longer code and code where the functionality repeats but the objects change.
Am I thinking about JavaScript functions with-in functions correctly and is this a design goal of the langue to add long repeating extended functions with-in functions?
Here, you should understand 2 things:
passing functions as arguments
anonymous functions
The first concept is particulary important because callbacks are popular in JavaScript, so let me explain it for callbacks. Imagine we have 2 functions getStuffFromWeb and processStuff. You probably expect that they are used like this:
var result = getStuffFromWeb();
processStuff(result);
But the issue here is waiting for getStuffFromWeb may take some time (the server is busy), so instead they are usually used in a "when you finish, call this function" manner, which is:
var getStuffFromWeb = function(params,callback) {
...
callback(result);
};
getStuffFromWeb(someParams,processStuff);
Well, in fact the structure of getStuffFromWeb will be different, most likely something like this:
var getStuffFromWeb = function(params,callback) {
requestObject.make_request(params)
.onSuccess(callback);
};
So when getStuffFromWeb is called, it starts to listen to response while the code after getStuffFromWeb(someParams,processStuff); goes on evaluating. When the response comes, it calls the callback function to process the data further using the procedure we have defined (processStuff).
The second concept is rather simple: you may of'course write smth like
var processStuff = function() {...};
var getStuffFromWeb = function(params,callback) {
requestObject.make_request(params)
.onSuccess(callback);
};
getStuffFromWeb(someParams,processStuff);
but if you use processStuff only once, why define a named function? Instead, you can just put the very same expression inside the onSuccess param like this:
var getStuffFromWeb = function(params) {
requestObject.make_request(params)
.onSuccess(function() {...});
};
getStuffFromWeb(someParams);
This looks exactly like if we took the value of processStuff and put it directly to the onSuccess's argument (and that's called anonymous function). And also we got rid of an extra argument of getStuffFromWeb.
So basically that's it.
Simple answer is that the second argument of click() requires a callback function.
This can be a named function passed as reference as in your p_obj.click(do_click); example or it can be an anonymous function with self contained logic. Anonymous functions are very common in javascript
It's the same thing just with 2 different ways of declaring the callback.
Note that the only time you would return anything from an event handler function would be to return false which effectively prevents the default browser event (url opening from href or form submit for examples) and stops event propagating up the DOM tree
main is a function name with a return type of var.
No. main is a variable which is assigned an anonymous function. The function name would go between the keyword function and the () containing the argument list.
It has no return statement so it returns undefined.
$('.article') is a element/object/or class object.
It is a call to the function $ with one argument. The return value is a jQuery object.
.click() is a call to a member function
Pretty much. In JavaScript we call any function that is the value of a property of an object as method.
This seems to be a newly on the spot created function
function () { } is a function expression. It creates a function, exactly like the one used to assign a value to main earlier. This question is worth reading for more on the subject.
When/If click() is activated or run.
The click function is called immediately. The new function is passed as an argument.
The purpose of the click function is to bind a click event handler so that when a click event hits the element later on, it will trigger the function passed as an argument.
I do realize my c -like example is wrong and odd. I realize my terminology is wrong or otherwise used incorrectly.
Leaving aside vagaries of syntax. The main difference here is that the click event handler function is that the event handler function is stored in an intermediary variable.
You can do that in JavaScript just as easily, and then reuse the function elsewhere in the code.
var main = function(){
function show_specific_description() {
$('.description').hide();
$(this).children('.description').show();
}
$('.article').click(show_specific_description);
show_specific_description.call($(".article").last()[0]);
};
main();
is this a design goal of the langue to add long repeating extended functions with-in functions?
No. Passing a function expression as an argument is a convenient way to be more concise when you don't want to reuse the function. It's not the only way to pass functions about.
main is currently a function.
It is possible to be overwritten (even to a different type). var is not the return type, it's a statement that main is a variable.
All values should be declared as variables, within the highest scope you intend them to be used (in JS, scope typically means functions, not blocks).
You have the right idea, suspecting that the function gets passed in, and called at a later point in time (and this is actually one of the harder parts for people to get, coming from certain other languages). You'll see this behaviour all through JS.
One key thing to keep in mind in this language (you haven't hit it yet, but you will) is that JS is lexically scoped.
function getInnerX () {
var x = 5;
function getX () {
return x;
};
return getX;
}
var x = 10;
var getX = getInnerX();
console.log(getX()); // 5
The function getX inside of getInnerX has access to the references around it, at the point where it's defined (not where it's called), and thus has live access to the inner x, even if its value changes over time.
This will be another important piece of understanding what you see going on in the language, especially in the case of callbacks.

what is the difference between these two

I'm very new to js so I'd appreciate some help. I have two blocks of code that I think should work identically but don't. Can someone explain how they're different? It looks like in the first piece of code, the parser enters the function directly.
function embedGameSwfAfterReg() {
embedGameSwf("{$swfLocation}", "100%", "100%", {$flashVars});
}
API.registerOnload(embedGameSwfAfterReg())
and
API.registerOnload(function() {
embedGameSwfAfterReg("{$swfLocation}", "100%", "100%", {$flashVars});
});
In the first code block, you're registering the result of the embedGameSwfAfterReg function (undefined) as the onload function (() means you're evaluating the function). Remove the parentheses to have the embedGameSwfAfterReg function itself registered:
API.registerOnload(embedGameSwfAfterReg)
This
API.registerOnload(embedGameSwfAfterReg())
runs embedGameSwfAfterReg, and then passes the return value (undefined since it doesn't return a value), to registerOnLoad
you want
API.registerOnload(embedGameSwfAfterReg)
which passes the function itself to registerOnload
Functions are objects in Javascript and can be passed directly by their names. When you add the parens, it instead runs the function and passes the result.
function embedGameSwfAfterReg() {
embedGameSwf("{$swfLocation}", "100%", "100%", {$flashVars});
}
API.registerOnload(embedGameSwfAfterReg)
and
API.registerOnload(function() {
embedGameSwfAfterReg("{$swfLocation}", "100%", "100%", {$flashVars});
});
would work the same way.
The difference is () which you have put with embedGameSwfAfterReg function in the first case
It actually calls the function there only but its different in the 2nd case.
I'm asssuming that the second example should be
API.registerOnload(function() {
embedGameSwf("{$swfLocation}", "100%", "100%", {$flashVars});
});
If so, then the difference is quite big. In the first case, the embedGameSwfAfterReg function is invoked and the embedGameSwf is called when you register. This is probably not what you want since the the return value of the function is undefined.
In the second case, the anonymous function is not invoked until later when the registerOnLoad event is raised. This is probably what you want.
API.registerOnload() takes a callback function as parameter, therefore you only have to pass in the function name as reference, otherwise the function is directly getting called when the code runs.
// Correct form is:
API.registerOnload(embedGameSWFAfterReg)
Your second sample already is an anonymous function that is handled like an function callback and therefore evaluated when API.registerOnload(callback) is calling the reference with callback() somewhere inside it's code.
Short answer:
First piece of code do nothing, because embedGameSwfAfterReg doesn't have a return statement. Probably it could even end up with an error if API.registerOnload doesn't accurately check its arguments before execution.
Second piece of code creates an anonymous-function that is passed as an argument to API.registerOnload method which (as far as I can see from method name) runs functions during an Onload event.
Long answer:
In the first piece of code you declare a new function named embedGameSwfAfterReg which resists in global-scope of your code:
function embedGameSwfAfterReg() {
// calls embedGameSwf function
}
after, you execute defined function and pass the result to registerOnload method of an object named API:
API.registerOnload(embedGameSwfAfterReg());
As you probably mentioned, declared function embedGameSwfAfterReg has no return statement, so the result of its execution will be undefined. In other words
API.registerOnload(embedGameSwfAfterReg());
is doing the same as
embedGameSwfAfterReg();
API.registerOnload();
so eventually it calls API.registerOnload() WITHOUT any arguments passed!
Second piece of code creates an anonymous function (functions are specific objects in JS, which can be passed to other functions/methods, have its own methods and executed). Then it passes created function (or better say a reference to the function) to registerOnload - method of an object called "API".
You should read topics about Objects, Function-type, scopes, anonymous functions and closures in JS. I would advise Mozilla JavaScript guide
Also feels free to play with a simplified example at jsfiddle which gives some practical hint on anonymous functions in JS.

Categories