Javascript: How to get callback's parameters - javascript

I'm trying to somewhat replicate the functionality of forEach so that I can understand it better. In forEach you can pass it in an anonymous function with a parameter 'item' and then it would give you the items in the array. So how is this done exactly? Below I have a function print where I call another function a with an anonymous function as parameter. So how can I extract the parameter called 'param' from the anonymous function and use it in a's definition.
function print() {
var param = 'param1'
a(function(param) {
console.log('execute a')
})
}
function a(fn) {
//how can i access the fn's parameter list here?
//execute fn and do something with its parameter
fn()
}
print()
What I'm trying to accomplish: Run the function "a" and execute the anonymous function passed into it along with its parameters

You're completely misunderstanding parameters.
Your callback is a function. Its parameters are passed by the code that calls it (in a()), just like any other function.
If you want to pass a parameter to a(), you should pass it like any other parameter.
The fact that your callback's parameter happens to have the same name as a local variable is completely irrelevant.

Related

Javascript same method signature

Can someone please explain why we can simply pass a method name to a higher order function and everything works just fine. I know in something like Java I have to call the method words on each element individually. I was told that in Javascript if method signature matches we can simply pass in the name of the function with () and it will work. It is great but I want to know whats going on in the background. Why are we able to do this in javascript ?
function words(str) {
return str.split(" ");
}
var sentences = function(newArr){
return newArr.map(words);
}
In many languages you can pass a reference to a function as an argument to a function. That then allows the host function to use that argument and call that function when appropriate. That's all that is going on in Javascript. When you pass the name of a function without the () after it, you're just passing a reference to the function. That enables the host function to use that function as an argument and call it some time later.
In your specific example, .map() expects you to pass in a function that it will call once for each item in an array. So, you pass the name of a function that will then get called multiple times, once for each item in the array. That function you pass has a bit of a contract that it has to meet. It will be passed three arguments (value, index, array) and it must return a value that will be used to construct a new array.
In Javascript, since there is no argument type checking by the language, it is the developer's responsibility to make sure the arguments of the function you are passing match what the caller of that function will actually pass to it and you have to consult documentation of the calling code itself to know what arguments will be passed to it. You can name the arguments anything you want (that is entirely internal to your function implementation), but the order and the quantity of the arguments is determined by the caller and you must declare your function to match what the caller will provide.
Once thing that confused many in Javascript.
If you pass just a function name, you are passing a reference to the function (something that the host function can call at some later time).
array.map(myFn) // passes a function reference
Or, use an inline function (same outcome):
array.map(function(value, index, arr) {
// code goes here
})
If you put parens at the end of the function name, then the function is executed immediately and the return value of that function execution is what is passed:
array.push(myFn()); // pushes the result of calling myFn()
You are calling the words function repeatedly. You're calling it for each iteration of the map function.
The map function takes a callback which it runs for every iteration. That callback is usually in the form of
function (elementOfNewArr, indexOfNewArr, newArr) { }
Because functions are objects, you can store them on a variable and use that new variable name to call that function, instead of its original one. That's mostly the use of functions as objects. You can toss them around.
let foo = function () { return 'jasper!'; }
let boo = foo;
let ron = boo; // ron() will now return 'jasper!'
So, what you've done is plop in your callback function, though it was defined elsewhere. Since callback functions, like all functions are objects, you can declare that callback function, "saving" it to whatever variable you want and use it in anywhere that you can use it normally.
This is super useful if you have to use the same function in more than one place.
What I believe you are misunderstanding is that functions themselves can be treated the same as other variables in javascript. Consider this example:
var newArr = [1,2,3,4];
newArr.map(function(item){
return item * item;
});
In the above example, a function is passed as an argument to the map() function. Notice that it is described anonymously (no function name given). You can accomplish the exact same thing like this:
var newArr = [1,2,3,4];
function squared(item){
return item * item;
}
newArr.map(squared);
These two examples achieve the same thing, except in the second example, rather than writing the function in place, we define it earlier in the code. If it helps, you can even create the function in the same way as you would any other regular variable:
var squared = function(item){
return item * item;
};
You can pass this function around the same way. If you want to know the difference between defining functions in these ways try var functionName = function() {} vs function functionName() {}

javascript function with parameter called without parameter?

I was checking out an example of javascript code from w3schools:
http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_geolocation
If function showPosition by definition has a parameter called position:
function showPosition(position) {... }
why is it possible to call it with no parameters:
navigator.geolocation.getCurrentPosition(showPosition);
Example is functional, just trying to understand it
In fact am surprised showPosition has a param at all. Would you change that?
That's not calling the function, it's passing the function as an argument to another function. getCurrentPosition uses the argument as a callback, and it will later call the function with the appropriate argument.
A function call always has parentheses after the function name, e.g. showPosition(something).
There is arguments array-like object in JS which allows to skip actual parameters at all and use arguments[0] for position in your case.

Javascript arguments object

I am having a hard time understanding the arguments object. In this code, what function would arguments be looking at?
getAjax('get_info', 'java_array', realVarName, cld.listArray, 0, '',
'no_restrict', function() {
show_list(arguments[0], sld);
if (typeof(postFunc) == "function") {
postFunc();
}
});
'arguments' is an inherit variable with any function. It contains all the parameters passed to a function. For instance, a function definition may not list any parameters, however an invocation could include 'n' parameters on it. The function could then still access all of them through the arguments array.
The arguments object is an Array-like object corresponding to the arguments passed to a function.
In your code the arguments[0] will primarily be undefined
First off, arguments is an object that represents the set of arguments passed to the current function. It exists automatically inside of every function. You can read more about it here on MDN.
So, in your case, arguments[0] will be the first argument that getAjax() passes to the callback you passed into it as the last argument when you called getAjax(). So, it depends upon the internal behavior of getAjax() which you do not show us.
Let's walk through how your code works:
You make a function call to getAjax() and pass it a number of arguments.
One of those arguments is a callback function (the last argument).
When getAjax() is doing its job, it will, at some point, call that callback function.
When it calls that callback function, it can pass that callback some arguments.
Within that callback function the arguments object will represent whatever arguments were passed to it by getAjax().
So, when (in that callback function), you then get arguments[0] and pass it to show_list(), you will be passing whatever the first argument was that getAjax() passed to your callback.
You could rewrite your code without using the arguments object like this by just declaring a named argument for your callback:
getAjax('get_info', 'java_array', realVarName, cld.listArray, 0, '',
'no_restrict', function(obj) {
show_list(obj, sld);
if (typeof(postFunc) == "function") {
postFunc();
}
});
In this alternate implementation, you name the first argument to the callback function to be obj and use it directly rather than using arugments[0]. Both your implementation and this produce the same result.
It is generally better to use named arguments (like the obj in my alternate implementation) when you know what arguments are going to be passed to a function as this makes the code more self documenting. But the arguments object can be particularly useful when you don't know how many arguments are going to be passed to a function or when you want to pass whatever arguments were passed to your function to some other function (forwarding or proxying).

What's the meaning of "()" in a function call?

Now, I usually call a function (that requires no arguments) with () like this:
myFunction(); //there's empty parens
Except in jQuery calls where I can get away with:
$('#foo').bind('click', myFunction); //no parens
Fine. But recently I saw this comment here on SO:
"Consider using setTimeout(monitor, 100); instead of setTimeout('monitor()', 100);. Eval is evil :)"
Yikes! Are we really eval()-ing a string here? I guess I don't really understand the significance and implications of 'calling' a function. What are the real rules about calling and referring to functions?
In JavaScript functions are first-class objects. That means you can pass functions around as parameters to a function, or treat them as variables in general.
Let's say we are talking about a function hello,
function hello() {
alert('yo');
}
When we simply write
hello
we are referring to the function which doesn't execute it's contents. But when we add the parens () after the function name,
hello()
then we are actually calling the function which will alert "yo" on the screen.
The bind method in jQuery accepts the type of event (string) and a function as its arguments. In your example, you are passing the type - "click" and the actual function as an argument.
Have you seen Inception? Consider this contrived example which might make things clearer. Since functions are first-class objects in JavaScript, we can pass and return a function from within a function. So let's create a function that returns a function when invoked, and the returned function also returns another function when invoked.
function reality() {
return function() {
return function() {
alert('in a Limbo');
}
};
}
Here reality is a function, reality() is a function, and reality()() is a function as well. However reality()()() is not a function, but simply undefined as we are not returning a function (we aren't returning anything) from the innermost function.
So for the reality function example, you could have passed any of the following to jQuery's bind.
$('#foo').bind('click', reality);
$('#foo').bind('click', reality());
$('#foo').bind('click', reality()());
Your jQuery bind example is similar to setTimeout(monitor, 100);, you are passing a reference of a function object as an argument.
Passing a string to the setTimeout/setInterval methods should be avoided for the same reasons you should avoid eval and the Function constructor when it is unnecessary.
The code passed as a string will be evaluated and run in the global execution context, which can give you "scope issues", consider the following example:
// a global function
var f = function () {
alert('global');
};
(function () {
// a local function
var f = function() {
alert('local');
};
setTimeout('f()', 100); // will alert "global"
setTimeout(f, 100); // will alert "local"
})();
The first setTimeout call in the above example, will execute the global f function, because the evaluated code has no access to the local lexical scope of the anonymous function.
If you pass the reference of a function object to the setTimeout method -like in the second setTimeout call- the exact same function you refer in the current scope will be executed.
You are not doing the same thing in your jQuery example as in the second setTimeout example - in your code you are passing the function and binding the click event.
In the first setTimout example, the monitor function is passed in and can be invoked directly, in the second, the sting monitor() is passed in and needs to be evaled.
When passing a function around, you use the function name. When invoking it, you need to use the ().
Eval will invoke what is passed in, so a () is required for a successful function invocation.
First of all, "()" is not part of the function name.
It is syntax used to make function calls.
First, you bind a function to an identifier name by either using a function declaration:
function x() {
return "blah";
}
... or by using a function expression:
var x = function() {
return "blah";
};
Now, whenever you want to run this function, you use the parens:
x();
The setTimeout function accepts both and identifier to a function, or a string as the first argument...
setTimeout(x, 1000);
setTimeout("x()", 1000);
If you supply an identifier, then it will get called as a function.
If you supply an string, than it will be evaluated (executed).
The first method (supplying an identifier) is preferred ...

passing a function as a parameter?

Here is my event and as you can see I want to send a function with it as a parameter.
onclick="deleteItems('image', 'size', function(){GetImageSize();})"
The delete function is in a js file. In my js file I want to call my GetImageSize() function.
var deleteItems = function(module, controller, callback) {
callback(); // ??????????
}
I want to do this so I can rebuild my table when my ajax call has finished.
Hope you guys can help me
Regards Örvar
You can refer to the function, without calling it--just don't use the ending parens. The parens mean you're calling the function. In the case of passing the function into another function as a callback you want to leave the parens off. (And you don't need the anonymous function declaration around it.) It should read:
onclick="deleteItems('image', 'size', GetImageSize);"
JavaScript functions are first class objects. You could store functions in variables and pass them around as arguments to functions. Every function is actually a Function object.
Therefore, if you have a GetImageSize() function, you can simply pass it to the deleteItems() function just like any other variable:
deleteItems('image', 'size', GetImageSize);

Categories