44: JavaScript functions
11th October 2012: Material moved to webplatform.org
The Opera web standards curriculum has now been moved to the docs section of the W3C webplatform.org site. Go there to find updated versions of these docs, and much more besides!
12th April 2012: This article is obsolete
The web standards curriculum has been donated to the W3C web education community group, to become part of a much bigger educational resource. It is constantly being updated so that it remains current with modern web design practices and technologies. To find the most up-to-date web standards curriculum, visit the web education community group Wiki. Please make changes to this Wiki yourself, or suggest changes to Chris Mills, who is also the chair of the web education community group.
- Previous article—The principles of unobtrusive JavaScript
- Next article—Objects in JavaScript
- Table of contents
Introduction
Functions lie at the core of practically everything useful that you’ll do with JavaScript. Broadly speaking, they offer the ability to break a program into logical chunks, each implementing a specific piece of functionality. They’re a central feature of the language, and a good chunk of JavaScript’s attractiveness is due to the particular ways in which it enables you to use and create functions. If you’ve done some programming before in languages like PHP or Java, you’ll feel right at home with functions in JavaScript; if not, don’t worry. Functions are critical, but they’re not hard to wrap your head around. This article explains why you’ll want to understand functions, then dives into their syntax and shows you how to create and use them.
Note that the functions examples are available for download, as well as being linked to at appropriate places in the article below.
The structure of this article is as follows:
What and why
You certainly don’t want to reach for your specifications to refresh your memory each time you need to perform a specific calculation; it's much better to simply code the calculation’s steps once, bundle that up as a calculateSomething
function, and then point to that implementation next time you need to perform the same activity. This simple act of bundling up a set of commands means that you can concentrate on the activities that your code implements instead of the intimate details of those activities’ internal steps. You can think of the functions you write as a layer sitting on top of JavaScript’s built-in core; you’re creating new commands that are more expressive and more understandable in the context of your particular application.
With that in mind, the “why?” of functions has a very straightforward answer: they are the basic building blocks that allow you to structure your code to enhance understanding of its purpose, and to reuse the functions you’ve written to avoid writing the same bits of code in multiple places. Your program will be easier to write and test if you break it into small pieces, each with a defined task.
Moreover, breaking your code up into well thought-out functions makes maintaining your code in the future much easier. Imagine, for example, that the rules for daylight savings time are changed again next year. If you’ve done that calculation eighty-five times throughout your project, you will introduce new bugs when you update the code in each of those locations; it’s repetitive, manual, and failure-prone. On the other hand, changing a single calculateDaylightSavings
function allows you to cascade that single change down through the rest of your program with a single fix, much the same as the CSS cascade of style down through the page. In this way, functions make maintenance much less error prone, and easier to implement successfully.
A Function’s syntax
Defining your own function is a simple task. As an example, let’s build a function that generates a random background colour for an element on a page:
function setElementBackground() {
var red = Math.floor(Math.random() * 256);
var green = Math.floor(Math.random() * 256);
var blue = Math.floor(Math.random() * 256);
var obj = document.getElementById('element_to_change');
if ( obj ) {
obj.style.background = 'rgb(' + red + ',' + green + ',' + blue + ')';
}
}
Without worrying too much about the code executed by the function, I’d like you to focus at this moment on 4 important features of the function’s syntax:
- A function declaration always begins with the keyword
function
, which makes sense. - The next bit is the function’s name, in this case
setElementBackground
(I generally use camelCase for function names). The name of the function is important, as it’s the bit you have to remember in order to use and reuse the code. Make sure it's an accurate description of what the function does; I’m sure you’ll agree thatsetElementBackground
is a much better, more descriptive function name than something likecoloursAreNice
orcrazySetter
. - Directly after the function’s name come a pair of parentheses. Inside these come the functions argument list, which enables you to make your functions more generic, and thus more reusable—you can apply them to more situations more easily. This is a powerful concept, but optional, so I’ll discuss it in more detail in the next section.
- Finally comes a pair of curly-brackets containing some code: these signify a block of code in JavaScript. Everything inside this block will be executed when the function is called, in order, just like any other bit of JavaScript code you’ve written.
Using the function
Now we’ve defined the function, to call it somewhere in your code you would simply write:
setElementBackground();
That's all there is to it! You no longer have to concern yourself with the difficult internal details of setElementBackground
; you’ve already written the code, so now you’re able to use it with ease wherever you like, and reap the (random) rewards of reuse.
Now, the function I’ve just written is completely self-contained. It performs some activity, then exits; it neither needs input from the code that called it, nor does it give any information back to its caller about what happened. JavaScript, of course, allows us to write code that’s a bit more talkative and flexible than that, so let’s have a look at how we deal with information input to and output from functions.
Arguments
Passing information into a function in order to influence its behavior is a great way to make it more flexible and useful in a variety of situations. For example, I’ve hard-coded the id
of the element whose background is changed inside setElementBackground
; it would be nice to be able to specify different elements on the page whenever I call the function so that I could reuse this function for different elements, instead of duplicating all that code. Arguments are the solution.
Earlier, I noted that the function’s definition contains a set of parentheses directly after the function’s name. This is the function’s argument list. To accept input from the caller, just specify a comma-separated list of variables that your function would like to receive. You can specify as many or as few as you’d like, and the names you use in the argument list can be referenced inside the function’s body just like with any other variable. The updated setElementBackground
function looks like so (check out the first example improvement live):
function setElementBackground( elementID ) {
var red = Math.floor(Math.random() * 256);
var green = Math.floor(Math.random() * 256);
var blue = Math.floor(Math.random() * 256);
var obj = document.getElementById( elementID );
if ( obj ) {
obj.style.background = 'rgb(' + red + ',' + green + ',' + blue + ')';
}
}
Calling this function with an element ID passed in as an argument is straightforward:
setElementBackground( 'element_to_change' );
If you accidentally call the function without passing in an argument, it takes the value undefined
. You can test for this inside your function body to provide a bit of defense against unintentional misuse:
if ( elementID == undefined) {
// This will evaluate to `true` if the `elementID`
// variable wasn't provided by the caller.
// You can then write some code inside this
//if statement to stop the code from erroring.
}
The confusing, but nice, bit about function arguments is that the names of variables in the argument list have nothing to do with the name of variables passed into the function. If elementID
is defined as the function’s argument, JavaScript creates a variable inside the function named elementID
that has no effect on any variables outside the function — you can have another function outside the function of the same name, and its value would not be altered as a result of any statements inside the function. For example:
var elementID = "No change!";
setElementBackground( 'element_to_change' );
alert( elementID ); // Alerts "No change!";
This has a very important side effect. Arguments and variables defined within a function are scoped locally, that is, they are not available from outside of the function nor have any effect on similarly named variables in the global scope. I’ll talk a bit more about this concept (called scope) in the Objects and JavaScript best practices articles, but for now, let’s look at a quick example. I’ll define a substring
function accepting a string and a starting point:
function substring( obj, start ) {
obj = obj.substring(8);
}
var myString = "This is a string!";
substring(myString, 8);
alert(myString); // Alerts "This is a string!"
Even though the obj
variable is reassigned inside the function to the result of the built-in substring
method, myString
isn’t affected at all; only the copy of myString
sitting inside substring
was changed. The external variable has no idea at all that anything has happened.
This raises the question of communication: if changing arguments’ values has no effect outside the function, how do you pass information back from a function to it’s caller? Let's look at this now.
Return values
It’s very common indeed for a function to do some calculation, and give the result of that work back to its caller to be used elsewhere. It might be useful, for example, for our setElementBackground
function to return an array of the colour values for use elsewhere. That’s a simple matter of using the return
keyword JavaScript provides, as shown here:
function setElementBackground( elementID ) {
var red = Math.floor(Math.random() * 256);
var green = Math.floor(Math.random() * 256);
var blue = Math.floor(Math.random() * 256);
var obj = document.getElementById( elementID );
if ( obj ) {
obj.style.background = 'rgb(' + red + ',' + green + ',' + blue + ')';
}
return [ red, green, blue ];
}
check out the second example improvement in action.
That simple addition means that you can now call the function in such a way as to capture its result in a variable:
var my_result = setElementBackground('element_to_change');
Even if your function doesn’t need to return a value, or has no real value to return, it’s good practice to indicate success or failure by returning true
or false
, respectively. With that in mind, I’ll change setElementBackground
to return false
if the elementID
that was passed in doesn’t actually exist:
function setElementBackground( elementID ) {
var red = Math.floor(Math.random() * 256);
var green = Math.floor(Math.random() * 256);
var blue = Math.floor(Math.random() * 256);
var obj = document.getElementById( elementID );
if ( obj ) {
obj.style.background = 'rgb(' + red + ',' + green + ',' + blue + ')';
return [ red, green, blue ];
} else {
return false;
}
}
check out the third example improvement in action.
This allows you to check that the code executed properly by testing its return value, for example:
if ( !setElementBackground('element_does_not_exist') ) {
alert("Something went wrong! `element_does_not_exist` doesn't exist!");
}
Additionally, please note that the return
keyword actually ends execution of your function right when it’s called, returning execution to the place at which your function was called. Code sitting below the call to return
is not executed — it’s simply ignored.
Summary
With that, you now know pretty much everything you need to in order to begin sprinkling your code full of functions. They’re a foundational part of good JavaScript code and your programs will be better organized, clearer and more readable, and easier to comprehend if you take the opportunity to wrap code up in well-named functions for reuse.
Exercise questions
- What are functions? Why are they useful?
- How do you define a function?
- How do you pass information into a function? Why would you want to? Conversely, how can you get information out of a function?
- Wouldn’t it be nice if you could pass a colour array into `setElementBackground`? Try modifying the code to accept another argument, and use that variable inside the function to override the random background colour.
- Previous article—The principles of unobtrusive JavaScript
- Next article—Objects in JavaScript
- Table of contents
About the author
Mike West is a philosophy student cleverly disguised as an experienced and successful web developer. He’s been working with the web for over a decade, most recently on the team responsible for building up Yahoo!’s European news sites.
After abandoning suburban Texas’ wide open plains in 2005, Mike settled in Munich, Germany where he’s struggling with the language less and less every day. mikewest.org is his home on the web, (slowly) gathering his writings and links together for posterity. He keeps his code on GitHub.
padding-bottom:50px;This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.
Comments
The forum archive of this article is still available on My Opera.
LIJE Creative
Friday, March 8, 2013
By the way, if you guys want to try this out, use this code:
--
LIJE Creative