By the end of today, you will be able to:
Three metaphors:
A function allows us to package up a chunk of code and give it a name. We can run that code later by invoking (or calling) the function.
We define a function like this:
function name_of_function () { // body of function } function yo () { alert("Hey there!"); }
We invoke a function using its name and parens:
yo();
Using parameters, we can make functions that are more powerful and general.
var
tan = Math.sin(angle)/Math.cos(angle); // compute tangent of angle tan = "#FFCC99"; // store a shade of tan
yo
alert
A bunch of JavaScript attendees, in full costume, are playing a party game, “Who am I?” They give you a clue, and you try to guess who they are, based on what they say. Assume they always tell the truth about themselves.
CLUE: I get passed into a function.
parameter
argument
global variable
local variable
CLUE: I am everywhere
CLUE: Where I can be seen
return
scope
You are given two alternative definitions of a function:
function displayDate() { var today = new Date(); document.querySelector("#date").innerHTML = today.toLocaleDateString(); }
function displayDate(dateStr, elemID) { if(dateStr == "now") { var date = new Date(); } else { var date = new Date(dateStr); } document.querySelector(elemID).innerHTML = date.toLocaleDateString(); }
Which of the following statements is true? Explain your answer.
The two definitions are equivalent.
Definition 1 is better than Definition 2.
Definition 2 is better than Definition 1.
Definition 2 is longer than Definition 1.
Given definition 2, how can we display the current date? The date for Valentine's day? How would we do those for definition 1?
Which of the following function/method calls causes a side effect instead of returning a value.
parseInt()
prompt("Enter your name:")
document.querySelector("#fred")
alert("Hello")
What is the effect of executing the following code:
/* a and b are the lengths of two adjacent sides of triangle, and angle is the number of degrees between them. */ function isEquilateral(a, b, angle) { if (a == b && angle == 60) return true; } alert(isEquilateral(10,10,90));
true
false
NaN
undefined
The point is that if a function is supposed to return a value, it should probably always return a value (unless some kind of error has occurred or some unusual situation). Above, the isEquilateral function should answer the question is this a square and so it should always answer true or false and therefore always return a boolean.
isEquilateral
is this a square
Recall that scope tells us where a variable exists and can be used. Variables that usable in every function are called global. Variables that are usable only in one function are called local.
What is the result of the following statements?
var restaurantBill = 100; function amountToPay(amount){ amount = amount + 0.0625 * amount // add state tax return amount } amountToPay(restaurantBill); console.log(restaurantBill);
100
106.25
Note the difference between the global variable restaurantBill and the parameter amount. The parameter is generic, since the function could be used in a wide variety of situations. The global is particular to a situation. We might also have globals like gymCharge and barTab, keeping track of different parts of our spending.
restaurantBill
amount
gymCharge
barTab
Note also that the name for the global and the name for the local are unrelated. It's a common misconception that they must be the same.
One important point about the code above is that if a function returns a value, the caller should almost always receive and use that value. Of course, the function might also have a side-effect which is the reason it's being called.
If it doesn't have a side-effect, and the return value is being ignored, the function invocation is useless.
Define a function named amountToPay2, based on the amountToPay function from the last quiz question to include a second parameter that is the state tax rate, so that it can calculate the amount to pay depending on a buyer's state. You can invoke the function a few times to test it, like this:
amountToPay2
amountToPay
alert(amountToPay2(100, 4.0)); // NY tax alert(amountToPay2(100, 7.5)); // CA tax
Your solution might look like this:
function amountToPay2(amount, stateRate) { amount = amount + (stateRate/100) * amount; // add state tax return amount; } alert(amountToPay2(100, 4.0)); // NY tax alert(amountToPay2(100, 7.5)); // CA tax
The trick we just saw makes the function more general by replacing a constant in the code with a parameter, and then requiring the caller to supply the value. This then gives the caller the freedom to provide other values. The amountToPay2 function can do everything that the amountToPay function does, plus a lot more. After all, the original function only worked for Massachusetts; the revision works for all 50 states, plus the District of Columbia.
Replacing constants with parameters is a pretty common technique; keep it in mind.
Of course, the general function is a bit less convenient, because you have to supply the tax rate (and maybe you don't even know it!). Suppose we only had the general function and we wanted to define the specific version for Massachusetts.
Define a function named amountToPayMass, using the the amountToPay2 function from the last exercise. It will only take one argument, the pre-tax bill and it will return the amount with Mass state tax added. You can invoke the function a few times to test it, like this:
amountToPayMass
alert(amountToPayMass(100)); alert(amountToPayMass(200));
function amountToPay2(amount, stateRate){ amount = amount + (stateRate/100) * amount; // add state tax return amount; } function amountToPayMass(amount){ return amountToPay2(amount,6.25); } alert(amountToPayMass(100)); alert(amountToPayMass(200));
That may seem surprising, but it's quite reasonable take a general function and make a more specific version just for the use we want to make of it.
More importantly, it's useful to think about the information flow here:
It's almost like a bucket brigade.
Let's do one last series of examples. I have implemented on this page a function named hexDigit. It takes a number from 0--15 and returns the corresponding digit in hexadecimal, as a string.
hexDigit
Define a function named hexByte that takes a number from 0--255 and returns the hexadecimal equivalent as a string. Your function should use the hexDigit function I defined. Here's what the function will need to do:
hexByte
You can test it like this:
alert(hexByte(15)); // "F" alert(hexByte(16)); // "10" alert(hexByte(160)); // "A0" alert(hexByte(255)); // "FF"
function hexByte(byte){ var quo = Math.floor( byte/16 ); var rem = byte - 16*quo; // or byte % 16 return hexDigit(quo)+hexDigit(rem); } alert(hexByte(15)); // "F" alert(hexByte(16)); // "10" alert(hexByte(160)); // "A0" alert(hexByte(255)); // "FF"
Now, let's build on that.
Define a function named hexColor that takes three inputs, an amount of red, green and blue, and returns a hex color specification. Your function should use the hexByte function from the previous exercise. Here's what the function will need to do:
hexColor
#
alert(hexColor(0,0,255)); // "#0000FF" alert(hexColor(128,128,128)); // "#808080" alert(hexColor(64,128,192)); // "#4080C0"
function hexByte(byte){ var quo = Math.floor( byte/16 ); var rem = byte - 16*quo; // or byte % 16 return hexDigit(quo)+hexDigit(rem); } function hexColor(r,g,b) { return "#"+hexByte(r)+hexByte(g)+hexByte(b); } alert(hexColor(0,0,255)); // "#0000FF" alert(hexColor(128,128,128)); // "#808080" alert(hexColor(64,128,192)); // "#4080C0"
Thank goodness for functions! Think of what a mess that code would be if we didn't have the hexByte function! That function makes the code for hexColor clear, concise and correct.
Now, let's put that to some use. Try the following function:
Note that this last function does not return a value; instead, it has a side-effect of changing the background color of the page.
In the next few lectures, we'll see how JavaScript can be used to manipulate our web pages, as we saw there.
We hope that after these activities you have a good understanding of:
Will be posted later, visit again after .
Quiz questions:
1a. B arguments are the values passed in 1b. C global variables are visible everywhere 1c. B "scope" is the term for where variables are visible 2. C The second function does everything the first does, and much more 3. D B has an effect as well as returning a value, so it does *both* 4. D undefined, since it doesn't return a value. It should return "false" 5. A the global variable is unaffected.
Exercise 1:
Exercise 2:
Exercise 3:
Exercise 4: