Where is the argument for this JavaScript callback function being defined? - javascript

I've been confused about callback functions for some time and I found a simple code snippet that illustrates my confusion. This is from w3schools:
var str = "Mr Blue has a blue house and a blue car";
var res = str.replace(/blue|house|car/gi, function (x) {
return x.toUpperCase();
});
This is a representative example of my confusion with callbacks. I don't understand how x in the argument function(x) is being populated. I'm looking at the documentation at MDN and I see that matches are being passed to x, but I don't understand the underlying principle. Is there a rule like " the argument of a callback function is populated by the previous argument," or is this behavior specific to String.replace()? How can I extrapolate and apply this to all callback functions that I find?

The replace function is called and passed two arguments.
The replace function (which is provided by the underlying JS engine, so its source code does not show up in your question) does stuff.
Among the stuff it does is call the function you pass as the second argument (newSubstr). When replace calls newSubstr, replace passes newSubstr an argument.
Is there a rule like " the argument of a callback function is populated by the previous argument,"
No. It is populated through whatever way the code calling the callback is designed to do.
this behavior specific to String.replace()?
Yes
How can I extrapolate and apply this to all callback functions that I find?
You can't.
Read their manuals or source code instead.

Related

function creation as a parameter?

I have tried asking this on specialty forums, and no one answers this for me, But I am hoping someone here can. Below is the snippet of code in question, and I know how it all works except for 2 bits of it.
this.data = allItems().filter(function(item) {
return this.includes(item);
}, this);
As stated above, I understand all but two bits of the code above: What is this type of function called? a call back? There is no function called "item" or a variable within the main function called "item". Lastly, why is "this" a part of the snippet?
Sorry if this isn't enough information, I am trying to be as thorough as I can with this question as I am not familiar with this style of scripting. I have done some research on this subject, and the closest explanation as I can get is a private function, but as I mentioned above, there is no function called "item" anywhere.
Javascript is a bit of a strange language. For those of us that learned a compiled programming language first, it shares a visual aesthetic but the behind-the-scenes are very different.The first thing to understand is that in javascript every function as a special reference called this. It references the current iteration of the function.
Think of it like this: there is a class called Human, which defines a set of properties common to all humans -- we have a height and weight, a name, eye color, hair color, etc. But me, being 5'8", 200 lbs, hazel eyed, and bald is not the same description as you, or any other human being. While there could definitely be another human with those characteristics, we are not the same.
var Human = function(name, height, weight, eye_color) {
this.name = name;
this.height = height;
this.weight = weight;
this.eye_color = eye_color;
}
var me = new Human('Jhecht', '5.8', 200, 'hazel');
alert(me.name); //Alerts 'Jhecht'
var you = new Human('Gatene', '6.0', 190, 'brown');
alert(you.name); //Alerts 'Gatene'
The this in the code ensures that the variables me and you mark us as individuals. This way, even though we can both have things in common, it is understood that we are not the same. It also makes it so that you can check on that information later. Without the this I would just be setting each variable equal to itself (name=name) which gives me no way to look at its contents later. If I removed the this.name and replaced it with name, I would no longer get my expected result if I tried to call alert(me.name)(I would most likely get an undefined value) When used on event listeners for HTML elements, this will refer to the HTML element, unless you tell it otherwise.
Functions in javascript are also a little less rigid (and I don't feel like that's the correct word, but it's the best one I've got) than functions in other languages. Notice in my code above I set my function like so:
var Human = function(name, height, weight, eye_color) ...
I could have also created that function like so:
function Human(name, height, weight, eye_color)...
and the outcome would be the same.
So in your code snippet, let's go through line by line.
this.data = allItems().filter(function(item) {
return this.includes(item);
}, this);
this.data is saying "the data variable on this instance of the function call this code is from" is equal to allItems() which presumably returns an array of items, is filtered down by a function. Since Javascript allows for something called 'anonymous' functions, aka functions without a name, we create an anonymous function (non-named function) which accepts a named argument of item.
the function being passed to the .filter method in line 1 will return the result of the includes method (most likely defined somewhere previously in your code), which was being passed the value of our argument from line 1, item.
Ends the function definition with }. the next portion goes back to what I said before, this refers to the current function call, unless you instruct it not to. the , this); is the programmer saying "on this function, which I declared above, I want this to refer to the object I am using currently."
This part is tricky, and it will definitely take some time to understand so if you're not entirely sure don't worry too much about it.
The filter function accepts a parameter. It is expected that this parameter will be a function with at least 1 parameters (item)
Your code snippet is passing an anonymous function as this parameter:
function(item) {
return this.includes(item);
}
thus fulfilling the expectations of the filter function
What is this type of function called? a call back?
It's an anonymous function (because it has no name), which is being passed as an argument to filter, and yes, it could be and is called a callback.
There is no function called "item" or a variable within the main function called "item".
You're misunderstanding basic function syntax. function(item) does not refer to anything called item, a function or otherwise. It is defining an anonymous function with item as its single formal parameter.
Lastly, why is "this" a part of the snippet?
Read the documentation for filter, and in particular the thisArg parameter, the second parameter, which specifies the value to use as this when the callback function is called. In this case, this is being specified, which is the this of the surrounding context, which is the same object which holds the property data, as well as the method known as includes.
It could be more easily written without using the thisArg parameter by using arrow functions, as
this.data = allItems().filter(item => this.includes(item));

Want to understand need of callback functions in javascript

I am new in learning JavaScript. I read about callback functions but I am unable to understand its real use.
So, please help by any real world example.
Below is small code depicting use of callback function in but that too is not clear to me.
var friends = ["Mike", "Stacy", "Andy", "Rick"];
​
friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick​
});
The uses of JavaScript callback functions are many. You probably already know that it's simply a function that we pass as an argument to another function. This means that we can have a function called foo. Lets says foo is some sort of method that runs an array through a sort, however the actual sorting function is variable. So we could use foo for every algorithm, by simply passing values like so.
foo([1,6,1,2], quickSort);
Assuming we have a quickSort method.
Generally speaking, callbacks are however used to call something AFTER a function has executed. So why not just call one function after the other, you say?
foo();
bar();
Why would you pass bar to foo ? Well, usually callbacks are used when dealing with asynchronicity. So, the bar function would get called way before, say an AJAX request gets a response, or before a setTimeout triggers it's callback.
As for the specific example you provided, it's simply a simplified way to iterate over an array. With the added benefit that you can use a named function, so you can declare it earlier and separate your code better.
Javascript is generally synchronous, i.e. commands are executed one after the other.
However there are times where you want a function to be asynchronous, so you call a function and don't want to wait for it to complete before you move on to your next task.
Callbacks are used by asynchronous functions. When the function completes, the callback function is run, without the rest of the code having to wait for it.
var friends = ["Mike", "Stacy", "Andy", "Rick"]; friends.forEach(function (element, index, array) { console.log((index+1) + "." + element ); });
The concept of Callbacks in JavaScript is that you can assign functions to variables.
Everthing, in JavaScript, except for simple types as string and number, are objects (and even those have functions to be called as they were objects as well).
Let's take your function for instance, as example:
Syntax
arr.forEach(callback[, thisArg])
Parameters
callback
Function to execute for each element, taking three arguments:
currentValue
The current element being processed in the array.
index
The index of the current element being processed in the array.
array
The array that forEach is being applied to.
thisArg
Optional. Value to use as this when executing callback.
It takes a callback function that will be called for each element.
Also, we have the definitions of asynchronous calls in JS (with a help of timeouts/interval and AJAX calls).
The idea of the callback functions doesn't stays just in JS. Anywhere it would be easier or just simples, to use a function passed as reference we have the concept of callback (it just goes insane with this feature of AJAX in js, that why it's so common to say JS is asynchronous).
You could read a litte more about it here:
http://www.sitepoint.com/javascript-goes-asynchronous-awesome/
In JavaScript, function below is an object:
function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick​
}
Let call this object A.
When you pass the code friends.forEach(A), browser will understand that when running through the array friends it will trigger A.
So at the end, callback function is just like you "define" function but you will use it later on.

Javascript callbacks/events

bunny.mousedown = function(mouseData){
text.setText(mouseData.global.x);
}
The 'setText' part gets called when someone presses on the bunny sprite. I'm using PIXIjs.
Hello, I'm new to JS and having a bit of a hard time understanding this code. As I understand, everything in JS is an object, including functions. In other languages that I've had experience with, you'd just use event listeners with this kind of thing.
Mousedown is a callback function, or so it says in the documentation. I think I understand what's a callback function. But, I'm confused at how it's implemented in the code above.
function display(s , callb){
alert(s);
callb(1 , 2);
}
function add(q, r){
alert((q + r).toString());
}
display("amidoindisrite?", add);
callb would be the callback function, I think... But, anyway, I don't understand how the code on the very top gets executed/called. Anyone have any ideas? What would be the equivalent in Java or Python if there is one? Thanks.
In your second example, callb is a pointer to a function, or the function definition if you like. If you apply the parentheses after it, it executes the function with the parameters provided (if any, integers 1 and 2 in this case). Other ways to execute a callback are the call() and apply() methods.
In the first example, the mousedown property expects a value that is a callback, i.e. the function definition. This example defines a function that assigned to this mousedown property. When the mousedown event is triggered for the bunny object, the mousedown property is executed (using parentheses, call() or apply(), that would depend upon the Pixjs library). That property being the function defined, the text.setText method is run.
I hope that clarifies it.

How to pass additional arguments to callback functions in javascript when using .execute()?

I'm working with javascript for Google Analytics API but I'm no more than a novice in JS. I have C++ and Java knowledge and I can get along with logical thinking but some things puzzle me. In GA API I get to make a function call like this:
gapi.client.analytics.data.ga.get({'ids':'<tableID>',
'start-date':'<startDate>',
'end-date':'<endDate>',
'metrics':'<metrics>',
'filters':'<filters>',
'samplingLevel':'HIGHER_PRECISION',}).execute(putToVar);
putToVar() is a user defined function defined like so:
function putToVar(results)
{
//do processing with the results
}
It is my understanding that the .execute() method is used to invoke a callback function for the asynchronous call gapi.client.analytics.data.ga.get(). So I assume what function1().execute(function2) does is call function2 with the return value from function1 as argument? Is this correct?
I'm in a situation where I need to apply several distinct filters and store them in an array to retrieve as and when required, irrespective of whether the API call returned a results object (it is an async call, so I don't know when the response comes, it is only visible to the callback function).
I would like to pass to the callback function the dimensions of the array in which to store the returned objects so that I can retrieve them on demand later, without worrying about the order in which the responses get processed. I say this because, initially I tried a for loop and the order in which I got the response to my API calls were not the same as the order in which I placed API calls for my queries, so there were mismatches.
Since the reference uses this method to invoke the callback function, I would like to know how to pass additional arguments to a callback function like this when using .execute() method, when I get to write putToVar() function something like this:
function putToVar(results,arrayDim)
{
//Process Results
//Store in Array[arrayDim] the required value
}
I hope I have made myself clear.
I have read the following posts
How do I pass multiple arguments into a javascript callback function?
passing arguments to callback
How to explain callbacks in plain english? How are they different from calling one function from another function?
How to pass additional arguments to callbacks and also access default parameters?
but none of them seem to use the .execute() method and I cannot figure out how to use what they have said. Or, if and how my .execute() method (type of callback execution) can be modified to help my purpose.
Adding a closure would solve your problem:
for(var x = 0; x< n x ++){ //Or any other loop
(function(x){ //Closure. This line does the magic!!
var arrayDim = something_that_depends_on_x_or_the_loop,
param2 = some_other_thing_that_depends_on_x;
gapi.client.analytics.data.ga.get({'ids':'<tableID>',
'start-date':'<startDate>',
...
}).execute(function putToVar(results){ //this fn is defined inline to get access to param1, param2
//The following alerts will use the *correct* variables thanks to the closure
alert(x);
alert(arrayDim);
alert(param2);
});
})(x); //This one too
}
The closure does the magic. It will allow to each loop cycle to have its own variables (not shared), so the proper ones will be inside putToVar when executed.
I hope it's clear, if not, just let me know.
Just test it!
Cheers, from La Paz, Bolivia

How does "makeAddFunction" in Eloquent JS work?

I'm trying to learn Javascript by reading Eloquent Javacript. I'm on the chapter dealing with functions and I'm stuck trying to figure out how the code below works. I don't see how the add function ever gets called. I see them calling addTwo and addFive but those names are different than add. The result of this code being run is 9. Can someone please explain this to me.
function makeAddFunction(amount) {
function add(number) {
return number + amount;
}
return add;
}
var addTwo = makeAddFunction(2);
var addFive = makeAddFunction(5);
show(addTwo(1) + addFive(1));
In makeAddFunction, a function is created, called add. This function is returned.
makeAddFunction is called twice with 2 different parameters, and stored in two variables, addTwo and addFive.
Calling addTwo() and addFive() is calling the functions created by add(), with the "amounts" 2 and 5 respectively.
addTwo(1) + addFive(1) == (1 + 2) + (1 + 5) == 9
Sometimes these types of 'closures' are called Builders, or Factories. The makeAddFunction 'builds' a special version of add based on the parameter you pass to makeAddFunction.
The addTwo function would look like:
function addTwo(number) {
return number + 2;
}
The makeAddFunction create a closure that sets amount as whatever number you pass in and returns a function that will add that amount to whatever number you pass to the new function and return it.
My best advice is you try to learn a bit about Javascript closures. Really. I might not be the answer you are looking for, but it is the best you can do if you want to understand what's happening there.
Get yourself a copy of any good javascript book. Let me suggest 'Javascript - The Good Parts' by Douglas Crockford.
For some of us, Javascript closures were not something we grokked. I hope it's easier for you.
Anyway, makeAddFunctionis a function creator. It creates new functions which are tied to the parameter you passed to makeAddFunction. Therefore, the addTwo variable receives and stores a new function, which you can invoke later by appending parentheses to it, i.e. addTwo().
The parameter you pass to addTwo, i.e. 1on invokation addTwo(1) is passed to the add function, because addTwo is nothing more than an add function where the amount var has a fix value of 2.
var addTwo = makeAddFunction(2);
When you call makeAddFunction(2) initially, the amount var is within its function scope where add can see it. addTwo now is set to the add function that makeAddFunction(2) returned.
addTwo(1)
Remember addTwo is now set to what makeAddFunction(2) returned, which is the function add, and amount is set to 2 within makeAddFunction(2)'s scope. add just returns its argument (1), plus the amount (2) in makeAddFunction(2)'s scope.
The same goes for addFive(5).
Javascript Ninja or The Good Parts are good reads that explain closures in detail. I'd highly suggest picking up those.
Follow the SO Linked/Related Questions on the right. Anyway ..
This is explained the article, albeit with a lot of fluff. Anyway, with a bit of fluff-cutting here is a "annotated" version:
.. functions [do] not just package up [some code to run], but also an environment. [..] a function defined inside another function retains access [to lexical variables (like "amount")] that existed in [the outer function] at the point when [the inner function] was defined.
Thus, the [inner] add function in the above example, which is created when makeAddFunction is called, captures an environment [including the "amount" variable of the outer function]. It packages this environment, together with [the code to run], into a value [(which is a fancy way to say functions are just objects)], which is then returned from the outer function.
When this returned function ([which has been assigned to] addTwo and addFive) is called, [the called function has access to] the captured environment ([and the "amount" variable which still contains the value initially passed to makeAddFunction]). These two values ([which are currently named by] "amount" and "number") are then added, and the result is returned.
I am not found of the original usage of "value" and have edit those parts a good bit - in JavaScript, variables (not values) are bound in closures.
Javascript relies pretty heavily on higher-order functions. Functions can be returned, assigned to variables, and passed around as values. This comes in handy in a lot of situations, especially when dealing with evented programming (JS's direct lineage from the its most prolific implementation in the browser.)
http://en.wikipedia.org/wiki/Higher-order_function
What you are seeing is a function that creates a function. It could be considered a "factory" for a function with one preset argument.

Categories

Resources