What is the relationship between a function and a value? - javascript

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.

Related

Why don't I pass any parameters to a function within map?

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;
});

JavaScript Closure and Invocation of function with two parens

First of all, the way the function is being called throws me off. How can a function be called with two separate parens like the one in this example?
addTogether(4)(3)
Lastly, could someone please explain how the closure works in this if statement(please see full code below)?
if(a) {
return function(y) {
if(checkIfNum(y)) {
return a + y;
} else {
return undefined;
}
};
If we call addTogether() like this:
addTogether(4)(3), I understand that argument a is set to 4 but not sure how y is set to 3.
function addTogether() {
function checkIfNum(num) {
return typeof num === 'number' ? num : undefined;
}
var a = checkIfNum(arguments[0]);
var b = checkIfNum(arguments[1]);//if there is no second argument, var b = undefined;
if(arguments.length > 1) {
return a && b ? a + b : undefined;
} else {
if(a) {
return function(y) {
if(checkIfNum(y)) {
return a + y;
} else {
return undefined;
}
};
} else {
return undefined;
}
}
}
console.log(addTogether(4)(3));//7
On the first invocation, addTogether(4), 'var a = checkIfNum(arguments[0]);' resolves to 'var a = 4'. The first invocation of addTogether() causes our anonymous function (y) to be invoked and returned to the main function addTogether(). When anonymous function (y) is invoked, JavaScript searches for the value of 'y'. How does JavaScript decide that '3' will be the value of 'y'? My guess is that on the first invocation of addTogether() or addTogether(4), the argument object associated with addTogether() is set to the value of 4. Once 4 gets passed to the function addTogether(), we now have 'a' = 4 trapped in the closure created by addTogether() and at the same time, essentially we have three things happening : #1 : 'a' = 4, # 2 : the argument of addTogether() is now set to the value of 3 or addTogether(3), #3 : anonymous function (y) is returned and invoked causing JavaScript to search for the value of 'y'. JavaScript sees that at this exact point in time, the argument of addTogether() is set to the value of 3 so JavaScript sets the value of 'y' to 3. How does JavaScript know to set 'y' to the value of 3? When a function is invoked inside another function, does JavaScript automatically set the value of the argument of the, for lack of better words, "child" function to the value of the argument of the "parent" function? Is there something about the arguments object that I'm missing here?
Great question. I remember scratching my head over this same example about two years ago.
For your first question, "How can a function be called with two separate parens like the one in this example?":
This is only possible because addTogether returns another function. You then pass that function another integer 3. It then adds them up to give you 7.
Then you ask about closures: a closure is formed when you add additional scope inside a scope giving the inner scope access to values in the outer scope. In this case a closure is formed when you declare a function within a function.
For your second question: "I understand that argument a is set to 4 but how y is set to 3":
Here's the logic of the function addTogether:
1) Check if one or two arguments are supplied.
2) If two arguments are supplied return the addition of the numbers iff they are both numbers.
3) If there is just one, return an anonymous function which takes an integer and adds its input to a variable a available to the anonymous function because of it being enclosed inside an outer function which declares a.
This is where the closure is formed. This anonymous function, since it is inside the scope of the outer function addTogether has access to all of the outer function's properties including a and the method checkIfNum.
In your actual case:
1) You supply one argument 3 so addTogether returns an anonymous function.
2) You call this anonymous function with a value of 3. This ends up running the logic in the anonymous function, first checking if 3 is a number, then adding 3 to 4, return 7.
I love JavaScript.

scope calling functions inside functions

Hope somebody finds the time to explain little about functions in functions and scoping.
I am trying to understand little more on functions and scope of variables and found a quite good tutorial, but this part I just do not get.
The task:
Create a function sum that will work like that: sum(a)(b) = a+b and accepts any number of brackets. Examples:
sum(1)(2) == 3
sum(5)(-1)(2) == 6
The solution:
function sum(a) {
var sum = a;
function f(b){
sum += b;
return f;
}
f.toString = function() { return sum };
return f; //line 12
}
alert( sum(1)(2) ); // 3e
The Explanation:
To make sum(1) callable as sum(1)(2), it must return a function.
The function can be either called or converted to a number with valueOf.
The solution is really self-explanatory:
My interpretation:
This f in function f(b) returned to the scope, which is from line 02 - 12.
The f in f.toString, is the currently returned f from function(b)
The next return f returns to the scope which is outside the function sum(a).
Problem:
I cannot figure out, where I need to think differently, because like I described above, the function would not be called again, so where is the part of the code, that make the 'several parentheses' possible?
Moreover, did I correctly assume where the fs are returned? Would be great if somebody would give some explanations.
The function sum returns a function, which we refer to as f.
The function f also returns a function: in fact, the function f returns itself.
When the function f is defined inside of sum, it gets permanent access to all variables currently visible in the scope chain. Here, it includes the locally-defined variable sum (the local running sum tally) and f (the function itself). (A "closure" is what we call the functional code of f along with all its in-scope variables.)
Because f returns itself, you can chain f with repeated calls:
var this_is_f = sum(1);
var same_f_again = this_is_f(2);
var f_a_third_time = same_f_again(3);
Or simply:
sum(1)(2)(3);
It is important to note that in my first example, I don't create new functions; instead, I just refer to the exact same function object with three different identifiers.
Each call to sum creates a brand-new f with a new local sum in its scope (here, I mean the local sum defined on the first line of the function named sum). However, calling the function sum does not clobber any old f, because each call to sum instantiates a new f (and knows nothing about any other fs that have been created on prior calls to sum). That way, you can have multiple tallies running:
var first_tally = sum(1)(2); // first: 3
var second tally = sum(4)(5); // second: 9
first_tally(3); // first: 6
second_tally(6); // second: 15
The reason you're able to see a meaningful result at any time is that f stingifies to the value of sum, instead of showing you its source code.
If you take this code and simplify it to the bare minimum I would be easier to understand. Take a function add that sums only 2 numbers:
function add(x,y) {
return x + y;
}
The above is a "normal" function. If you don't pass all the arguments you'll get unexpected results.
Now, if you want a function that adds 2 to any number, you could partially apply an argument to add, for example:
function add2(x) {
return add(2, x);
}
But in JavaScript we have first class functions (objects that can be passed around), so a function can take functions as inputs and return other functions. This is where "currying" comes in handy. While "partial application" lets you fix function arguments, "currying" takes a function of many arguments and breaks it down into a function of a single argument that returns another function of one single argument until all the arguments have been evaluated, in order, and then returns the result. For example:
function add(x) {
return function(y) {
return x + y;
}
}
Now you can create a function add2 by currying the function add:
var add2 = add(2);
add2(1); //=> 3
The normal function and the curried one have equivalent computations where:
add(1, 2) === add(1)(2)
This is what makes "several parentheses" possible.
In JavaScript "scope" and "closure" refer to functions but they're different concepts. A "scope" determines the reach/privacy of your variables while a "closure" lets you encapsulate code and carry it around. In the curried function above the variable x is kept in memory through closure because it's referenced inside the returned function object.
A particular limitation of "currying" is that you can't have functions of dynamic arity; the number of arguments must be fixed. This is not the case in the code you post where your sum function must be able to add a new number to the previous sum indefinitely.
Similarly to "currying" there's the idea of "generators"; a pattern to model sequences of lazy computation, in this case just adding a number to the previous sum on demand.
function sum(a) { // begin closure
var sum = a; // kept in memory...
function f(b) {
sum += b; //...because you use it here
return f;
}
f.toString = function() { return sum };
return f;
} // end closure
A different (maybe more clear) way to express your code would be to return an object to chain the computations, where you can either add a new number to the previous sum, or get the total sum so far:
function add(a) {
var sum = a;
return {
plus: function(b) {
sum += b;
return this;
},
sum: function() {
return sum;
}
}
}
add(1).plus(2).plus(3).sum(); //=> 6
In your code the returned function f acts as plus and toString as sum which retrieves the value.
Line 01-13 defines the function sum within the global scope.
Line 15 calls sum and changes scope to inside the function.
The variables a and sum and the closure function f are all defined in the function's scope - with the sum variable hiding the function definition from the global scope.
I'll skip over the toString bit here as its not important till later (when it gets very important).
The function sum finally returns a reference to the closure function f to the global scope as an anonymous function (since f can only be referenced by name from within its containing function's scope).
Back to line 15 - sum(1)(2) is the same as (sum(1))(2) and since sum(1) returns f then this can be reduced to (f)(2) or, more simply, f(2).
Calling f(2) adds 2 to sum - sum is defined in two scopes: as a function in the global scope; and as a variable (currently assigned the value of 1) within that function which hides the definition from the global scope - so, in f, the sum variable is set to 1+2=3.
Finally, in f, the function returns itself.
Back, again, to line 15 - f(2) returns f (although the named function f cannot be referenced in the global scope and, again , is treated as an anonymous function)
alert() is processed and the anonymous function (referred to as f) is converted to a string to be alerted; normally when alert() is called on a function it will display the source for the function (try commenting out Line 10 to see this). However, since f has a toString method (Line 10) then this is invoked and the value of sum (as defined in the function containing f) is returned and 3 is alerted.
Let's step through the function line by line:
function sum(a) {
This part is pretty self-explanatory; we have a function named sum which accepts an argument a.
var sum = a
Here we have a local variable called sum that is set to the value of the argument that is passed in.
function f(b) {
sum += b
return f
}
This is an inner function called f that accepts an argument called b. This b is then added to the value of sum from the outer scope (i.e., inside the scope of the function that is also called sum). After that, the function returns itself.
f.toString = function() { return sum }
This is the fun part! When you normally console.log a function, it will just spit out the function's source. Here we are redefining the toString method to instead be a function that spits out the value of sum. This is why you end up seeing the running total that is displayed instead of the function's source even though what you are returning is still a function.
Finally we have:
return f
So you basically have a function sum, returning a function that returns itself. The function sum basically sets everything up, but after calling sum(3), you then work with f, which you repeatedly call.
So the first time you call sum, you essentially get back this function:
function f(b) {
sum += b; //value of sum is 3
return f;
}
In this context, the value of sum will be the value of a that you passed into the initial call of the function sum. However, since the toString of f has been redefined, you only see the value 3. Then let's say you do sum(3)(4).
You get back, as before:
function f(b) {
sum += b; //value of sum is 3
return f;
}
But then you are actually calling f with an argument of 4 (basically f(4)). Since f is an inner function, it has full access to the scope of its parent function. This parent function (sum) is maintaining the the running total in a variable called sum, which is accessible to f. So when you now call f(4), you have b set to 4 and sum having a value of 3:
function f(b) { //b is 4
sum += b; //value of sum is 3 + 4, which is 7
return f;
}
So with each subsequent pair parentheses you are making repeated calls to the same f which is maintaining a running tally.
Another way is to think of sum as a kind of factory that can give you different f's, all of which keep their own running tallies (basically behaving like accumulators):
var firstSum = sum(4);
var secondSum = sum(2);
firstSum(5); //equivalent to sum(4)(5) returns 9
secondSum(2); //equivalent to sum(2)(2) returns 4
There are 3 concepts being played here
closures (no scope).
functions are first class OBJECTS in javascript (allows for chaining f(a)(b)(c)). There's no need to save a handle to the function to call it later.
I'll give you a run-down and then add some extra explanations afterwards
function sum(a) {
// when sum is called, sumHolder is created
var sumHolder = a;
// the function f is created and holds sumHolder (a closure on the parent environment)
function f(b) {
// do the addition
sumHolder += b;
// return a FUNCTION
return f;
}
// change the functions default toString method (another closure)
f.toString = function() {return sumHolder;}
// return a FUNCTION
return f
}
/*
* ok let's explain this piece by piece
*
* you call sum with a parameter
* - parameter is saved into sumHolder
* - a function is returned
*
* you call the returned function f with another parameter
* EXPLANATION: { sum(a) } returns f, so let's call f as this => {...}()
* - this private (priviledged) function adds whatever it's been passed
* - returns itself for re-execution, like a chain
*
* when it all ends {{{{}(a)}(b)}(c)} the remainder is a FUNCTION OBJECT
* this remainder is special in that it's toString() method has been changed
* so we can attempt to cast (juggle) it to string for (loose) comparison
*
*/
The concept behind closures is quite easy to understand but it's application make's your head spin until you get used to the idea that there is no function scope in javascript, there is closures and these are powerfull critters indeed
// this anonymous function has access to the global environment and window object
(function()
{// start this context
var manyVars, anotherFunc;
function someFunc() {
// has access to manyVars and anotherFunc
// creates its own context
};
anotherFunc = function () {
// has access to the same ENVIRONMENT
// creates its own context
};
}// whatever is in these keys is context that is not destroyed and
// will exist within other functions declared inside
// those functions have closure on their parent's environment
// and each one generates a new context
)();
Functions are first class objects. What does this mean? I'm not sure myself but let me explain with some further examples:
// how about calling an anonymous function just as its created
// *cant do the next line due to a language constraint
// function(){}()
// how about a set of parens, this way the word "function" is not the first expression
(function(){}());
// the function was created, called and forgotten
// but the closure inside MAY STILL EXIST
function whatDoIReturn() {
return function (){alert('this is legal');return 'somevalue';}();// and executed
}// returns 'somevalue'
Don't take this word for word. Go look for other people's code, check the Crockford and ask any and all questions that come up

Function arguments and how they work

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

Doing Math in Multiple Javascript Functions

I'm new to the Javascript world and trying to figure out this assignment my teacher assigned. Here is his description of what is expected:
Build a function that will start the program. Please call it start()
From the start() function, call a function called getValue()
The getValue() function will get a number from the user that will be squared.
Also from the start function, call a function called makeSquare()
The makeSquare() function will square the number that was received by the user in the getValue() function.
Make sure that you display the results of squaring the number inside of the makeSquare() function.
Here is what I have so far:
function start() {
getValue();
getSquare();
}
function getValue() {
var a = prompt("Number please")
}
function getSquare() {
var b = Math.pow(a)
document.write(b)
}
start()
This assignment doesn't have to be working with any HTML tags. I've only got the prompt box to work, nothing else does though. Am I using variables in a way that can't be used?
You were close. But it seems that you don't understand scoping and how exactly to use the pow function.
Math.pow:
Math.pow takes two parameters, the base and the exponent. In your example, you only provide the base. That will cause problems as the function will return the value undefined and set it to b. This is how it should have looked (if you wanted to square it):
Math.pow(a, 2);
Scoping:
Every function has it's own scope. You can access other variables and functions created outside the function from within the function. But you cannot access functions and variables created inside another function. Take the following example:
var c = 5;
function foo() { // we have our own scope
var a = c; // Okay
}
var b = a; // NOT okay. a is gone after the function exits.
We could say that a function is private. The only exception is that we can return a value from a function. We return values using the return keyword. The expression next to it is the return-value of the function:
function foo() {
return 5;
}
var a = foo(); // a === 5
foo() not only calls the function, but returns its return-value. A function with no return-value specified has a return value of undefined. Anyway, in your example you do this:
function getValue() {
var a = prompt("Number please")
}
and access it like this:
// ...
var b = Math.pow(a)
Do you see the error now? a is defined in the function, so it can't be accessed outside of it.
This should be the revised code (Note: always use semicolons. I included them in for you where necessary):
function start() {
getSquare();
}
function getValue() {
var a = prompt("Number please");
return a;
}
function getSquare() {
var b = Math.pow(getValue(), 2); // getValue() -> a -> prompt(...)
document.write(b);
}
start();
As this is an homerwork, I won't give you direct answer, but here's some clue.
In javascript variables are functions scoped. That mean that var a inside getValue is only available in there.
You can return a value from a function.
Functions are first class object in javascript, so you can pass them as parameter to other function and finally call them inside that function.
Am I using variables in a way that can't be used?
Yes, that's where your problem lies. Variables in most programming languages have a scope that determines where they're available. In your case, a and b are local variables of the functions getValue() and makeSquare() respectively. This means they're not available outside the function they're declared in.
Generally speaking, this is a good thing. You should use restricted scopes for your variables to make the "flow" of data through your program clearer. Use return values and parameters to pass data between functions instead of making your variables global:
function start() {
var a = getValue();
makeSquare(a);
}
// Return a value entered by the user
function getValue() {
return prompt("Number please")
}
// Write the square of the `a` parameter into the document
function makeSquare(a) {
var b = Math.pow(a)
document.write(b)
}
Your getValue() needs to return the value, so that you then can pass it to the getSquare() function.
In my opinion, you should always end each line with ;
You will probably need to parse the user input into a number. For that you can use parseFloat(string).
Math.pow takes two arguments, so to get the square, you would have to pass 2 as a second argument when calling it.
I edited your code with some clarifying comments:
function start() {
// Catch the value returned by the function
var value = getValue();
// Pass the returned value to the square-function
getSquare(value);
}
function getValue() {
// Parse the user input into a number, and return it
return parseFloat(prompt("Number please"));
}
// Let the square-function take the user input as an argument
function getSquare(a) {
// Math.pow takes a second argument, which is a number that specifies a power
var b = Math.pow(a, 2);
document.write(b);
}
start();
Another, less good way
In JavaScript, variable-scoping is based on functions. If a variable is declared using the var keyword, it is only available to that function, and its child-functions. If it is declared without the var keyword, or declared outside any function, it becomes a global variable, which will be accessible by any code run on that page.
That said, you could get rid of the var keyword inside the getValue() function, which would make the variable a global. You could then access it from within getSquare() the way you tried in your example.
This is generally not a good idea though, since you would "pollute" the global namespace, and you would be running the risk that you accidentally have another script using a global variable with the same name, which would cause all kinds of trouble, when the scripts start to work with the same variable.
You can try this.
<script type="type/javascript">
function start(){
makeSquare(getvalue());
}
function getvalue(){
return prompt("enter a number");
}
function makeSquare(a){
var result=Math.pow(a,2);
alert(result);
}
start();
</script>

Categories