javascript function with parameter called without parameter? - javascript

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.

Related

Passing a function as an argument

I am teaching myself javascript and one of the exercises I have tried makes no sense to me.
In the code below 'position' is a parameter that must be defined. However, when I pass the function, displayLocation as an argument to navigator.geolocation.getCurrentPosition, the code executes flawlessly, despite no argument being passed. When I try coords.longitude in the console without the position argument, it does not work.
How does the code work without a defined argument?
function displayLocation(position)
{
var latitude = latitude.coords.latitude;
var longitude = position.coords.longitude;
var div = document.getElementById("location");
div.innerHTML = latitude + " " + longitude;
}
navigator.geolocation.getCurrentPosition(displayLocation);
When I try coords.longitude in the console without the position
argument, it does not work...
How does the code work without a defined argument?
Arguments of function in JavaScript are optional.
If you don't pass it, it has as value : undefined.
So, yes the function accepts an invocation with a missing argument position but position.coords would not be usable.
navigator.geolocation.getCurrentPosition(displayLocation); calls your function with an instance of Position, as documented here.
Please take into account that displayLocation is not called immediately but delayed. This is why you pass it as a callback function.
What you are doing when you do
navigator.geolocation.getCurrentPosition(displayLocation);
is that you are calling navigator.geolocation.getCurrentPosition, and giving it a handle to your function displayLocation. You cannot say that displayLocation is getting called without an argument. That depends on what getCurrentPosition does with that handle. What it does is that it creates a position object, and then calls the function you gave it, with that object as a parameter. More succinctly, getCurrentPosition calls displayLocation with a position object, it created, as a parameter.
Let's take a look at Geolocation.getCurrentPosition. The required parameter success is a callback function.
Inner workings of the Geolocation.getCurrentPosition(displayLocation) will look roughly like the following:
function getCurrentPosition(callback, ...){
var positionGCP;
...
...
positionGCP = *someposition*;
// done getting current position
callback(positionGCP)
//passed in function gets called back!
}
and the last line (callback(positionGCP)) really runs displayLocation(positionGCP) since callback == displayLocation.
Does that make sense?
The following link may help:
Passing parameters to a callback function

Passing $('.class').each a function as arugment fails to run function

Here is the code that works perfectly
$('.picture').each(function(index) {
hideYourself(index);
});
However, when I try
$('.picture').each(hideYourself(index));
it doesn't run hideYourself. I thought it was maybe because I wasn't defining index but I don't define it when I pass it an anonymous function. CodePen of the whole program.
I know this might be a silly thing to be worried about but I am just confused on why passing .each a named function fails but passing it an anonymous function that calls my named function it works.
Use:
$('.picture').each(hideYourself);
Because each take one parameter function as argument but you actually invoking function using hideYourSelf(index) it invoked the function and returns the function return value as parameter to each.
You can achieve it as:
$('.picture').each(hideYourself);
or another way to achieve the same behavior is:
$('.picture').each(hideYourself());
function hideYourself(){
return function(index){
//hide here
}
}
first way is easy and better.

Javascript: How to get callback's parameters

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.

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).

Passing method parameters/arguments to method reference - bind, anonymous, named

I have multiple places in my code where i use method references(i.e. just the method name with no arguments) but I need to pass it specefic arguments.
I don't want to insert an anonymous method b.c. it makes the code unreadable.
I've told I can use the .bind method, but I don't know how to use it properly. Can some one elaborate on how to do this.
Here is one example of where I need to to to this.
How do I use bind to add in parameters to ajax_signin?
if(d===0){ajax('arche_model.php',serialize(c)+'&a=signin',ajax_signin,b);}
If you want ajax_signin() to get called with parameters, then you have to make a separate function that you can pass to ajax that calls ajax_signin() with the appropriate parameters. There are a couple ways to do this:
Using an anonymous function:
if(d===0){ajax('arche_model.php',serialize(c)+'&a=signin',function() {ajax_signin("parm1","parm2")},b);}
Creating your own named function:
function mySignIn() {
ajax_signin("parm1","parm2");
}
if(d===0){ajax('arche_model.php',serialize(c)+'&a=signin',mySignIn,b);}
If you want to use .bind() and you are sure you are only running in browsers that support .bind() or you have a shim to make .bind() always work, then you can do something like this:
if(d===0){ajax('arche_model.php',serialize(c)+'&a=signin',ajax_signin.bind(this, "parm1","parm2"),b);}
The .bind() call creates a new function that always has a specific this ptr and always has "parm1" and "parm2" as it's first two parameters.
You should be using partial function application! IE: The following:
// This will call a function using a reference with predefined arguments.
function partial(func, context /*, 0..n args */) {
var args = Array.prototype.slice.call(arguments, 2);
return function() {
var allArguments = args.concat(Array.prototype.slice.call(arguments));
return func.apply(context ? context : this, allArguments);
};
}
The first argument is the function you want to call, the second argument the context, and any arguments after that will be 'pre-loaded' into the function call.
Note: 'Context' is what this will refer to once the function is being executed.

Categories