I'm just trying to get a better understanding/confirmation of function arguments
In the function seen here:
function newFunction(data, status){
would the function apply specifically to data and status variables?
I don't quite understand how the arguments work.
Basic Scenario
When a function is defined, the () area is used for inputs. These inputs are mapped to what data is sent in.
function newFunction(data, status){
}
newFunction(1,2);
In this scenario, data will be assigned the value of 1, and status will be assigned the value of 2 for the scope of newFunction.
Missmatched inputs
However, it does not always directly map. If fewer arguments are sent, then the unassigned input variables become undefined.
function newFunction(data, status){
}
newFunction(1);
In this scenario, data will be assigned the value of 1, and status will be assigned the value of undefined for the scope of newFunction.
arguments object
Inside of the scope of newFunction, there is also access to the array like object called arguments.
function newFunction(data, status)
{
var args = arguments;
}
newFunction(1);
In this scenario, the variable args will hold the arguments object. There you can check args.length to see that only 1 argument was sent. args[0] will give you that argument value, being 1 in this case.
Function object
A function can be made into an object with the new keyword. By using the new keyword on a function, a Function object is made. Once the Function object is made, this may be used to refer to the current Function object instead of the global window.
function newFunction(data,status){
if( this instanceof newFunction ){
//use as a Function object
this.data = data;
}else{
//use as a normal function
}
}
var myNewFunction = new newFunction(1);
In this scenario, myNewFunction now holds a reference to a Function object, and can be accessed as an object through dot notation or indexing. myNewFunction["data"] and myNewFunction.data now both hold the value of 1.
This means that the function accepts both data and status parameters. The programmer calling the funciton (you) is required for providing the parameters when calling the function (also known as arguments.)
Let's look at a simplified example:
function add(x, y) {
return x + y;
}
The function here takes two numbers, adds them together, and returns the result. Now, as a programmer, you have the benefit of adding two numbers whenever you want without having to duplicate the functionality or copy/paste whenever you need your application to perform the same functionality.
Best of all, another programmer you work with can add two numbers together without worrying about how to do it, they can just call your function.
EDIT: Calling the function works as follows
var num1 = 10;
var num2 = 15;
var z = add(num1, num2); //z = 25
function newFunction(data, status){ ... function code ... }
This is the Javascript definition of a function called newFunction.
You can pass arguments to a function. These are variables, either numbers or strings, with which the function is supposed to do something.
Of course the function behaviour/output depends on the arguments you give it.
http://www.quirksmode.org/js/function.html
Related
How come we do not have to pass an argument to function b
in the code below? Is it just because we are using map method of type Array? Or is there anywhere else that we can use a function just like this in
JavaScript?
Can someone give a very clean and through explanation?
Code:
/* we have an array a*/
const a = ['a', 'b', 'c'];
/*we define a function called b to process a single element*/
const b = function(x){do something here};
/*I noticed that if we want to use function b to take care with the
elements in array a. we just need to do the following.*/
a.map(b);
Functions are first class citizens in Javascript, which is just a fancy way of saying they can be passed around as variables and arguments.
What you are doing when you call
a.map(b);
Is essentially calling
[
b('a'),
b('b'),
b('c')
]
The array function map just calls the given function (in your case b), with each argument in the array, and puts the output in a new array. So there are arguments being passed to b, it's just that map is doing it behind the scenes for you.
As for your other questions, there are plenty of cases where you'll pass a function as an argument without calling it first. Another common function is the Array object's reduce.
const out = a.reduce(function (accumulator, val) {
return accumulator + ' - ' + val;
}
// out: 'a - b - c'
Also a lot of functions take callbacks, that are called when some kind of asynchronous task is completed. For instance. setTimeout, will call a given function after the elapsed time.
setTimeout(function (){
console.log("Hello World!");
}, 1000
);
// Will print "Hello World!" to console after waiting 1 second (1000 milliseconds).
And you can easily write your function to take another function as an argument too! Just call the function you've passed in as you would any other function.
// A really basic example
// More or less the same as [0, 1, 2].map(...)
function callThreeTimes(f) {
return [
f(0),
f(1),
f(2)
]
}
// My function here returns the square of a given value
function square(val) { return val * val }
const out = callThreeTimes(square);
// out: [0, 1, 4]
You don't pass arguments to b because you're not calling it. You're passing the function itself as a value.
The use of map here is irrelevant; you can see what's happening directly:
const a = function(x) { alert(`called with ${x}`); };
// The function is NOT called here; it's just being assigned,
// like any other kind of value. This causes "b" to become
// another name for "a".
// This is NOT the same as a(), which would call the function
// with undefined as the argument.
const b = a;
// Now we call it, and the alert happens here
b(5);
Passing a function to another function works the same way, since it's just another form of assignment.
This is useful because you can tell other code how to do something even if you yourself don't know what the arguments are. In the particular case of map, it loops over the array for you and calls the function once for each element. You don't want to be calling the function you pass to map, because the entire purpose of map is to call the function for you.
map accepts function as a parameter and executes provided function for every element of an array.
Here you are passing function b as a parameter to map, hence map executes function b for every elements of array a.
So you do not need to pass arguments to function b here, map will take care of this.
You probably heard that functions are first class citizens in javascript.
If you look at the docs from MDN map you will notice that the map function accepts a callback with up to 3 arguments first one being currentValue
So let's break it down. A very explicit example of doing a map over the array above would be this one
a.map(function(currentValue, index, array){
// here you can access the 3 parameters from the function declaration
});
This function is called on each iteration of the array. Since functions are very flexible in javascript, you could only declare 1 parameter or even none if you want to.
a.map(function(currentValue){
// we need only the current value
});
Every function in JavaScript is a Function object. Source here
This means that every function is just a reference in the memory, meaning it can be specified either directly as an anonymous function (which is our case above), or declared before like this
function b(currentValue){
// this will be called on each item in the array
};
a.map(b)
This piece of code iterates over each element in the array and calls the reference we passed it (function b). It actually calls it with all the 3 parameters from the documentation.
[
b('a',0,a),
b('b',1,a),
b('c',1,a)
]
But since our function b only declared one, we can access the value only.
The other arguments are stored in the so-called Arguments object
Take from here Every function in JavaScript is a Function object which makes every function a reference to a certain memory location which in the end leaves us with a lot of flexibility of passing the function as a parameter however we want to (explicit via an anonymous function, or implicit via a function declaration (reference) )
how come we do not have to pass argument to function b here?
Simply because as per spec, map calls the b with 3 implicitly.
callbackfn is called with three arguments: the value of the element,
the index of the element, and the object being traversed
For each element in the array, callback function is invoked with these three arguments
value of the element (a, b and c in your case)
index of the element
b itself (object being traversed).
Why there are no parenthesis?
When you are passing a function as an argument to the sort method it doesnt have parentheses after the function name. This is because the function is not supposed to be called right then and there but rather the map method to have a reference to this function so that it can call it as needed while it's trying to map the array.
Why it does not take any arguments?
Now we know that map will be calling this callback function accordingly, so when map calls it it implicitly passes the arguments to it while calling it.
For example if this would be callback of sort then the argument passed will be current element and next element. If this is a callback for map then the arguments will be current value, index, array.
In JavaScript, functions are just another type of object.
Calling a function without arguments is done as follows. This will always execute the function and return the function's return value.
var returnValue = b();
Removing the parenthesis will instead treat the function itself as a variable, that can be passed around in other variables, arguments etc.
var myFunction = b;
At any point such adding parenthesis to the "function variable" will execute the function it refers to and return the return value.
var returnValue = myFunction();
var sameReturnValue = b();
So map() accepts one argument, which is of type function (no parenthesis). It will then call this function (parenthesis) for each element in the array.
Bellow you will find how to use the map function:
first Methode
incrementByOne = function (element) {
return element + 1;
}
myArray = [1,2,3,4];
myArray.map(incrementByOne); // returns [2,3,4,5]
Seconde methode
myArray = [0,1,2,3];
myArray.map(function (element) {
return element + 1;
}); // returns [1,2,3,4]
Third Methode
myArray = [1,2,3,4];
myArray.map(element => {
return element + 1;
});
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() {}
I'm using a cordova sqlite plugin. My question does not require you to have an understanding of the API. I'm not having any issues. I'm just a little uncertain about my understanding of the code below and how it works. I'm trying to have a much better understanding of the code I write.
So first, this variable "db" is defined as being a function (object) named "openDatabase" with parameters that the plugin understands and it's being called.
"db" which is actually a function (object) called "openDatabase" has a method called "transaction".
Am I doing alright so far?
Here's where I get a little confused: The db variable which is now equivalent to the openDatabase function has a method called transaction and it has a self invoking function as a parameter and the self invoking function has this variable "tx" as a parameter? Where does "tx" come from? Is it an object the "openDatabase" function returns after it's called? or is it not returned from "openDatabase" and it's just simply an object from the plugin? Is it always safe to assume variables as parameters that I haven't defined anywhere, that work, have been defined in the plugin, library or API I'm using? My last question is, why use a self invoking function as a parameter instead of a variable defined as that self invoking function? Any benefit? Thank you.
var db = openDatabase("DBTest", "1.0", "Sample Description", 200000);
db.transaction(function(tx) {
tx.executeSql("SELECT * FROM Table1Test", [], function(tx, result) {
for (var i = 0, item = null; i < result.rows.length; i++) {
item = result.rows.item(i);
document.getElementById('results').innerHTML +=
'<li><span> + item['text'] + '</span></li>';
}
});
Here's what's happening in that code, then I get to your specific questions:
db is being set to the return value from openDatabase. Then, the code calls db.transaction, passing in a callback function. The callback is called by db.transaction, which supplies the tx value, and in the callback we call tx.executeSql, passing in a second callback function. executeSql calls that second callback with the results, which code inside the second callback loops through.
Your questions:
So first, this variable "db" is defined as being a function (object) named "openDatabase" with parameters that the plugin understands and it's being called.
No. openDatabase is being called, and db is being set to its return value. That return value appears to be an object, but not a function (although it could be, there's no evidence that it is and it probably isn't).
"db" which is actually a function (object) called "openDatabase" has a method called "transaction".
Yes, except that db is probably not a function (although it could be), it's just an object.
The db variable which is now equivalent to the openDatabase function...
It isn't.
...has a method called transaction and it has a self invoking function as a parameter...
It's not self-invoking.
...and the self invoking function has this variable "tx" as a parameter? Where does "tx" come from?
Because the callback function isn't self-invoking, the tx argument's value comes from whoever calls the callback. The code in the transaction method will call the anonymous callback in that code. When it does, it will supply the value of the tx argument to that function. Similarly, the callback passed into executeSql will get called with values for tx and result.
Is it always safe to assume variables as parameters that I haven't defined anywhere...
Probably not. Instead, continue your study of JavaScript (you're clearly in the process of learning, which is great). You'll learn the syntax and be able to tell what's an argument, what's a variable, etc. Here's some info on that as comments:
var db = openDatabase("DBTest", "1.0", "Sample Description", 200000);
// ^^---- variable
db.transaction(function(tx) {
// Argument ------------^^
tx.executeSql("SELECT * FROM Table1Test", [], function(tx, result) {
// Arguments ----------------------------------------------^^--^^^^^^
for (var i = 0, item = null; i < result.rows.length; i++) {
// Variables ----^------^^^^
item = result.rows.item(i);
document.getElementById('results').innerHTML +=
'<li><span>' +
item['text'] + '</span></li>';
}
});
});
Part of the confusion here seems to be with callbacks, so let's look at a much simpler version of callbacks, and one where we can see both sides of it.
Suppose something provides us a function, countUp, which we can give a start and end value to, and which will then call us with each value between:
countUp(0, 5, function(value) {
console.log(value);
});
And suppose when we use that, we get:
0
1
2
3
4
In our code above, we create but never call the callback we're passing to countUp. It's countUp's code that calls the callback. Here's what countUp might look like:
function countUp(start, end, callback) {
// ^^^^^^^^---- the callback argument
var i;
for (i = start; i < end; ++i) {
// vvvvvvvv------- calls our callback
callback(i);
// ^----- passing in this, which we get as `value`
}
}
Live Example:
function countUp(start, end, callback) {
var i;
for (i = start; i < end; ++i) {
callback(i);
}
}
countUp(0, 5, function(value) {
snippet.log(value);
});
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
So first, this variable "db" is defined as being a function (object) named "openDatabase" with parameters that the plugin understands and it's being called.
No. The function stored in openDatabase is called and it's return value is assigned to db.
"db" which is actually a function (object) called "openDatabase" has a method called "transaction".
The value assigned to db is an object.
It might be a function, but there's no evidence in the code to suggest that it is.
It does have a method called transaction.
it has a self invoking function as a parameter
No, it doesn't.
foo( function () { } );
bar( function () { }() );
foo has a function as an argument.
bar has the return value of an immediately invoked function expression as an argument.
You can't have an IIFE as an argument itself because the IIFE resolves before the value is passed to the function.
transaction has a function passed as an argument.
Where does "tx" come from?
The transaction function (assuming the anonymous function doesn't get passed around some more first) will call the anonymous function. It will pass it arguments when it does.
Is it always safe to assume variables as parameters that I haven't defined anywhere, that work, have been defined in the plugin, library or API I'm using?
Yes
My last question is, why use a self invoking function as a parameter instead of a variable defined as that self invoking function?
If you mean Why use a function expression instead of a function stored in a variable? then it just saves the step of creating the variable and it keeps all the code together.
openDatabase is a funtion which returns an object that gets assigned to the db variable. This object has a method, transaction, which takes a function as an argument. When you call the transaction method, it sets up a transaction and then calls the function you pass it, with the newly-created transaction as its argument (the tx in your example). The function can now use the transaction to query the database. When it returns, the transaction method will do any necessary cleanup, and then return to the toplevel code.
This is too long for a comment yet doesn't directly answer the question. However, understanding this concept will hopefully allow you to answer all your questions yourself. Therefore I'm posting this as an answer.
Main concept: Functions are just objects just like numbers, strings etc.
You've probably seen code that looks like this:
var x = function (a) {...}
That is not a special syntax to declare functions. It is merely possible because functions are first class in javascript. First-class refers to things in the programming language that can be treated as data. In most languages numbers and arrays are first-class "things" (I'll avoid using the word "object" for now because it may have specific meanings in some languages, javascript included). In a lot of languages strings are also first-class things. In a few languages even functions are first class things.
Javascript is one language where functions are first-class: they can be treated as data
function x () {};
// you can assign them to variables:
var y = x;
y(); // call the function
// you can put them in arrays:
var a = [x,y];
a[0](); // call the function
// you can pass them as argument:
funtion b (foo) {
foo(); // call the function passed to b()
}
b(x); // this will cause b() to call x()
So when you see this:
db.transaction(function(tx) {/*...*/});
it's basically doing this:
function my_function (tx) {/*...*/}
db.transaction(my_function);
Therefore, you can sort of guess that db.transaction() looks something like this:
db.transaction = function (another_function) {
/* complicated processing ... */
another_function(result); // pass result variable to the function
// the user gave us.
}
So when you call:
db.transaction(function(tx) {/*...*/});
the function db.transaction() will call your function and pass it an argument (which you have defined as tx).
Think of tx as sort of the return value from db.transaction().
What is the relationship between a function and a value? I thought that a function was a type of value; however, functions both contain values (arguments) and return values too.
I'm (obviously) new to programming, and want to ensure that I have a solid conceptual foundation as I move my way through JavaScript.
Functions do things. Variables hold values (data).
A function can accept data as arguments. A function can also return data, but does not have to. Consider this function which just adds two numbers together:
function addNumbers(numberA, numberB) {
var total = numberA + numberB;
console.log(total);
}
This is a function which accepts two arguments. Within the function's code block, those arguments' values are assigned to the variables numberA and numberB. The function's code creates another variable, total, and assigns the value of numberA added to the value of numberB. The function then calls another function, console.log, with the value of total passed in as an argument.
Now, the function can also return values. Let's modify this function a bit:
function addNumbers(numberA, numberB) {
var total = numberA + numberB;
return total;
}
If you were to call this function now, you get back the value of total. If I were to run this:
console.log(addNumbers(5, 5));
You would see 10 in the console. My number literal values were passed as arguments to addNumbers. The function did its work and returned to me the value of its total variable. This value is now passed in as an argument to console.log.
If that isn't crystal clear yet, then please read other tutorials online before continuing.
Now, in JavaScript functions are just like anything else. You can assign them to variables as well!
var newAddNumbers = addNumbers;
console.log(newAddNumbers(5, 5)); // Also returns 10 in the console
When you type:
function someFunction () {
This is no different than:
var someFunction = function () {
The function itself is assigned to the variable someFunction. In our original example, the function itself was assigned to addNumbers. So yes, function is a type just like number, object, boolean, etc.
If I have a function:
function add(a, b) {
return a + b;
}
add is a function. All functions are values; I can place them in a variable or pass them as an argument, for example.
a and b are arguments of add, but the function has not been called, so they do not have values. Similarly, the function has been called, so it has no return value.
When I call the function:
add(1, 2);
The function executes with a and b initially set to 1 and 2 respectively for that invocation.
If I call it again with different arguments:
add(3, 4);
Then this time a and b are initially set to 3 and 4; however, these a and b not only have different values than the last time; they really are different variables. Every time you call a function, the arguments are essentially variables, which are local not only to that function but to that invocation of that function.
My programing background is that I learned a little Java in school. JavaScript syntax tends to confuse me for some reason. The JavaScript code below is a pattern of syntax that I don't know what to make of:
foo.ready = function(variable){... var whatever = variable.bar();
One of my main points of confusion is the parameter. For a contrasting example, in Java, if I call a method with one parameter, the call sends one parameter. I don't see how the parameter named 'variable' is ever set.
The variable is assigned when foo.ready is invoked, and passed some value (presumably a function).
var foo = {}; // 1. Create an object named "foo"
// 2. Assign a function to the "ready" property of "foo"
foo.ready = function(variable) {
// 4. "foo.ready" has been invoked, and received a function to its
// "variable" parameter, which it then invokes.
// The return value is assigned to "whatever"
var whatever = variable();
alert( whatever ); // 5. alert the value returned from the function
};
// 3. Invoke "foo.ready" passing a function as the argument.
// The function merely returns a string
foo.ready( function() { return "Hello world"; } );
Here's a working example: http://jsfiddle.net/69grz/
variable can be much more than a real variable, it can also be a function or a handler/object. In this case you call the function bar() on the object variable
foo.ready refers to an entire function. You can call foo.ready(), with any number of arguments, too. This is a typical call-back pattern: Whoever is in charge of the foo object wants to call you back when she's ready, so you pass this function to her.
You can't really control how many variables (of any type!) will be passed to your function, but presumably the documentation will have told you that you'll receive at least one.
Here is some code that makes that work:
// foo is an object
var foo = {};
// Create a function and assign to the ready property
foo.ready = function(variable){
var whatever = variable.bar();
};
// Create an object that contains a function named bar
var x = {
bar: function(){ return 42; }
};
// Call the function in foo with the object as parameter
foo.ready(x);
The expression variable.bar() will call the function in the object x which returns the value 42, which is then assigned to the variable whatever.