Post by Jordan on Dec 14, 2010 20:10:33 GMT
Functions are a part of nearly every scripting and programming language, and for good reason. The basic motivation for using functions is so you only have to write code once and then can reuse that code as much as you need to. It also provides a logical way to organize your code which is very important when you are working on large projects by yourself or with others.
Take a look at the function below. Each time it is called it will display a popup box containing the message "Hello World". This isn't very useful, but the main thing to get from this example is the syntax. You have the keyword "function" followed by the function name followed by a set of parenthesis. All of your instructions then go inside the brackets.
function show()
{
alert("Hello World");
}
// further down in the page...
// call the function somewhere
show();
Functions can take parameters which are local function variables that copy the values you pass into the function (note that objects are passed by reference, see "Value vs Reference" section below). If you wanted more than one parameter you would just need to add a comma and then insert the name of the next parameter.
function show(message){
alert(message);
}
// further down in the page...
// call the function somewhere
show("Hello World");
show("Hello again");
show("and again...");
Parameters are extremely useful and should be used rather than global variables. In other words, pass in all your values through a parameter list rather than declaring a lot of global variables and then using them in the function. For example, the function below removes a node from the DOM by going to its parent and then removing it as a child with the predefined "removeChild" function. Using a global variable this way is a bad practice because if you ever wanted to reuse this function or give it to a friend it wouldn't work since "element" would be undefined.
// Grab the welcome table
var element = document.getElementsByTagName("table")[0];
function removeElement()
{
element.parentNode.removeChild(element);
}
removeElement();
Instead, use a parameter so you can use the function on any node.
function removeElement(obj)
{
obj.parentNode.removeChild(obj);
}
// Remove the welcome table
removeElement(document.getElementsByTagName("table")[0]);
To be safe, you should also add an if statement which first checks to see if the node has a parentNode because if it doesn't the script will crash.
function removeElement(obj)
{
if(obj.parentNode)
obj.parentNode.removeChild(obj);
}
Functions can also return values with the "return" keyword. The function below squares and integer and returns the value.
function square(a)
{
return a * a;
}
variable = square(5); // variable equals 5 squared
variable == 25; // variable "is equal to" 25
This means you can also use functions as parameters in other functions. Below the square function is called twice, the first being a parameter for the second. square(5) is called and returns 25, and then square(25) is called and returns 625 which is then stored in "variable".
int variable = square(square(5));
To get some practice with functions, I recommend playing around with them here.
The following paragraphs go into a little more detail. It's good information and I recommend at least reading the "Value vs Reference" section.
An important detail about functions that you need to know is that any variables declared inside the function are local variables. What this means is that when the function is invoked all the variables declared inside it are created, used, and then destroyed during the lifetime of the function. They do not exist outside the function so you could have the same variable name in 1000 different functions and there would be no conflictions. This includes parameters which are actually copies of the values passed in (see "Value vs Reference" section below). As you can see in our square function above, a copy of "variable" is passed in. If I had just typed "square(variable);", the value of variable would not have changed because a copy of it's value was inserted into the local parameter "a" which was destroyed when the function completed its task. That's why we had to return the new value. It is a good practice to use local variables to create scope in your code so you don't have conflictions between other codes on the page.
This is why I recommend writing Proboard codes which only need to be called once with self invoking functions. A self invoking function is simply a function with no name that executes exactly where it is on the page like normal code. The difference from just typing the code out normally on the document is that the function creates a local scope for all your variables. If you are interested in this a good article can be found here. To just give you a quick example, I've turned one of the codes from my previous tutorial into a self invoking function.
(function() {
// This variable cannot be used outside this function
var a = document.getElementsByTagName("a");
for(i = 0; i < a.length; i++) {
if(a.href == "/index.cgi") {
a.href = "http://google.com";
}
}
})();
I would also like to point out that calling the getElementsByTagName() function over and over again is very inefficient. Most forums on Proboards have codes which use this function every time, but just calling it once is enough. If you ever code your own forum, create a global variable for each element that you call the function on and then just use that variable throughout your code. This would be a good example of using a global variable.
Value vs Reference
I also wanted to cover the difference between passing by value and passing by reference. In Javascript you don't have control over how the variable is passed so it's good to know what will happen. Primitive types such as integers and booleans (true/false) are going to be passed by value because they are small. Objects, however, which I will cover in another tutorial, are passed by reference because they are usually larger. A reference is really just the address of the object's location in memory. This address is usually the same amount of bytes as an integer (32-bit or 64-bit) so it's much faster to pass a copy of the address rather than a copy the entire object which could be huge. For example, I could make an object which would have a hundred integers and then be made up of other objects. If I needed to pass it to a function it would be very slow if it were done by value, but very quick if I just passed the address which tells the function where it's located.
What this means is that any changes you make to a parameter passed by reference will also change the original object that you passed in. Remember that passing by value does not change the original value.
function doSomething(obj)
{
// We are directly changing the objects HTML
// This is NOT a copy of the first td element
obj.innerHTML = "Hello, I am Lindsey Lohan!";
}
// Pass a reference of the first td element on the page
// so any changes the function makes will effect td[0]
var td = document.getElementsByTagName("td");
doSomething(td[0]);
Here's another example of passing by value.
function square(a)
{
// a is passed a primitive type so it holds a copy
// of the original value. Therefore, the original value
// won't be changed so this function is useless without
// a return statement.
a = a * a;
}
int value = 2;
value = square(a);
value == 2; // value still equals 2 and not 4
Take a look at the function below. Each time it is called it will display a popup box containing the message "Hello World". This isn't very useful, but the main thing to get from this example is the syntax. You have the keyword "function" followed by the function name followed by a set of parenthesis. All of your instructions then go inside the brackets.
function show()
{
alert("Hello World");
}
// further down in the page...
// call the function somewhere
show();
Functions can take parameters which are local function variables that copy the values you pass into the function (note that objects are passed by reference, see "Value vs Reference" section below). If you wanted more than one parameter you would just need to add a comma and then insert the name of the next parameter.
function show(message){
alert(message);
}
// further down in the page...
// call the function somewhere
show("Hello World");
show("Hello again");
show("and again...");
Parameters are extremely useful and should be used rather than global variables. In other words, pass in all your values through a parameter list rather than declaring a lot of global variables and then using them in the function. For example, the function below removes a node from the DOM by going to its parent and then removing it as a child with the predefined "removeChild" function. Using a global variable this way is a bad practice because if you ever wanted to reuse this function or give it to a friend it wouldn't work since "element" would be undefined.
// Grab the welcome table
var element = document.getElementsByTagName("table")[0];
function removeElement()
{
element.parentNode.removeChild(element);
}
removeElement();
Instead, use a parameter so you can use the function on any node.
function removeElement(obj)
{
obj.parentNode.removeChild(obj);
}
// Remove the welcome table
removeElement(document.getElementsByTagName("table")[0]);
To be safe, you should also add an if statement which first checks to see if the node has a parentNode because if it doesn't the script will crash.
function removeElement(obj)
{
if(obj.parentNode)
obj.parentNode.removeChild(obj);
}
Functions can also return values with the "return" keyword. The function below squares and integer and returns the value.
function square(a)
{
return a * a;
}
variable = square(5); // variable equals 5 squared
variable == 25; // variable "is equal to" 25
This means you can also use functions as parameters in other functions. Below the square function is called twice, the first being a parameter for the second. square(5) is called and returns 25, and then square(25) is called and returns 625 which is then stored in "variable".
int variable = square(square(5));
To get some practice with functions, I recommend playing around with them here.
The following paragraphs go into a little more detail. It's good information and I recommend at least reading the "Value vs Reference" section.
An important detail about functions that you need to know is that any variables declared inside the function are local variables. What this means is that when the function is invoked all the variables declared inside it are created, used, and then destroyed during the lifetime of the function. They do not exist outside the function so you could have the same variable name in 1000 different functions and there would be no conflictions. This includes parameters which are actually copies of the values passed in (see "Value vs Reference" section below). As you can see in our square function above, a copy of "variable" is passed in. If I had just typed "square(variable);", the value of variable would not have changed because a copy of it's value was inserted into the local parameter "a" which was destroyed when the function completed its task. That's why we had to return the new value. It is a good practice to use local variables to create scope in your code so you don't have conflictions between other codes on the page.
This is why I recommend writing Proboard codes which only need to be called once with self invoking functions. A self invoking function is simply a function with no name that executes exactly where it is on the page like normal code. The difference from just typing the code out normally on the document is that the function creates a local scope for all your variables. If you are interested in this a good article can be found here. To just give you a quick example, I've turned one of the codes from my previous tutorial into a self invoking function.
(function() {
// This variable cannot be used outside this function
var a = document.getElementsByTagName("a");
for(i = 0; i < a.length; i++) {
if(a.href == "/index.cgi") {
a.href = "http://google.com";
}
}
})();
I would also like to point out that calling the getElementsByTagName() function over and over again is very inefficient. Most forums on Proboards have codes which use this function every time, but just calling it once is enough. If you ever code your own forum, create a global variable for each element that you call the function on and then just use that variable throughout your code. This would be a good example of using a global variable.
Value vs Reference
I also wanted to cover the difference between passing by value and passing by reference. In Javascript you don't have control over how the variable is passed so it's good to know what will happen. Primitive types such as integers and booleans (true/false) are going to be passed by value because they are small. Objects, however, which I will cover in another tutorial, are passed by reference because they are usually larger. A reference is really just the address of the object's location in memory. This address is usually the same amount of bytes as an integer (32-bit or 64-bit) so it's much faster to pass a copy of the address rather than a copy the entire object which could be huge. For example, I could make an object which would have a hundred integers and then be made up of other objects. If I needed to pass it to a function it would be very slow if it were done by value, but very quick if I just passed the address which tells the function where it's located.
What this means is that any changes you make to a parameter passed by reference will also change the original object that you passed in. Remember that passing by value does not change the original value.
function doSomething(obj)
{
// We are directly changing the objects HTML
// This is NOT a copy of the first td element
obj.innerHTML = "Hello, I am Lindsey Lohan!";
}
// Pass a reference of the first td element on the page
// so any changes the function makes will effect td[0]
var td = document.getElementsByTagName("td");
doSomething(td[0]);
Here's another example of passing by value.
function square(a)
{
// a is passed a primitive type so it holds a copy
// of the original value. Therefore, the original value
// won't be changed so this function is useless without
// a return statement.
a = a * a;
}
int value = 2;
value = square(a);
value == 2; // value still equals 2 and not 4