Functions are an important building block of JavaScript language.
JavaScript functions (like functions in many other programming languages) offer important key advantages. First, functions promote code-reuse. Second, functions allow programmers to develop modular code (modular codes are easier to maintain and extend). Third, functions promote consistency in behavior. When different callers invoke a common function, then they all run the same code and thus, see the same behavior.
In JavaScript, functions belong to the category of objects. However, if we were to use the typeof operator against a function name, then it would return "function" instead of "object". One useful upshot of the fact that functions are objects, is that we can assign functions to variables or even pass them as parameters to other functions.
Before proceeding further, let us understand two key properties of functions: arguments and returns values.
Arguments are a set of variables that a caller can pass to a function. A function can take any number of arguments (including zero) and uses these arguments as an input to its logic. If the caller passes extra arguments than what is defined in the function, then the function ignores these extra arguments. On the other hand, if the caller passes less number of arguments, then JavaScript sets the missing arguments as undefined.
Return value is a value that the function passes back to the caller. This value is, typically, based on the argument input and function uses these argument to compute the return value. However, it is not necessary for a function to return any value!
A function definition has several syntax elements. First, we need to provide "function" keyword to identify that the object is a function. Second, we can provide the name of the function, "funcCanDoMagic"; however, this step is optional and we can write functions with no names! Third, we can provide zero or more arguments. Fourth, we should enclose the body of the function within curly braces ({}). Last, but certainly not the least, a function can also return a value.
As an example, in the below code, "funcAddTwoNumbers" is a function that adds two numbers. It takes these two numbers as arguments (num1 and num2). Next, it computes their sum (variable retSum) and then returns the same. After we invoke the function, the returned value from the function is automatically assigned to the variable retValue.
<!doctype html> <html> <script type="text/javascript"> // A simple function to add two numbers. function funcAddTwoNumbers(num1, num2) { var retSum = num1 + num2; return retSum; } // Invoke the function. retValue = funcAddTwoNumbers(101, 280); // retValue is 381. </script> </html>
Unlike some other languages (such as C), we do not have to declare (provide the prototype of) the function first -- we can define it (which means provide the entire body of the function) and right away start using it. In addition, we do not have to specify the return type for a function.
Let us now look at some simple examples that implement functions.
The first example (provided below) offers two types of function implementations. The first implementation defines the function and gives it a name: "function funcCanDoMagic(doerIndex)". The second implementation defines a function and then in the very definition, it assigns the function to a variable: "var varCanDoMagic = function(doerIndex)". Since providing a function name is optional, we skip providing one for the second implementation; such functions are known as anonymous functions. Also, once we have assigned the function to the variable, we can simply use the variable name to invoke the function: "varCanDoMagic(1)".
Both of these functions do the same task -- combine the name of magic beings with their actions. For this task, they rely upon a global object, objMagic. The properties of objMagic hold the mapping of magical beings and their actions.
<!doctype html> <html> <div id="idDiv"></div> <script type="text/javascript"> // Get a handle of the div element. var elem = document.getElementById("idDiv"); // Define an object to store name/action pairs for magic beings! var objMagic = {"dragons": "fly", "wizards": "do magic", "griffins": "fly"}; // First implementation: define a simple function. function funcMagicAction(doer) { return objMagic[doer]; } // Invoke the function using its name. retStringDoes = funcMagicAction("dragons"); elem.innerHTML += retStringDoes; // Prints "fly". // Second implementation: define a function and store it as a variable. var varFunc = function(doer) { return objMagic[doer]; }; // Invoke the function using the variable. elem.innerHTML += varFunc("wizards"); // Prints "do magic". </script> </html>
Please note that since functions are objects, one can always assign an already defined function name to a variable. Thus, in the previous program, we can assign the funcCanDoMagic() to a variable even after the function has been defined: "x = funcCanDoMagic".
As noted earlier, a function does not necessarily have to return anything. Here is another implementation of the funcCanDoMagic() that moves the task of returning the string and printing it from the main program to the funcCanDoMagic() function itself. And, therefore, this function does not need to return anything.
<!doctype html> <html> <div id="idDiv"></div> <script type="text/javascript"> // Get a handle of the div element. var elem = document.getElementById("idDiv"); // Define an object to store name/action pairs for magic beings! var objMagic = {"dragons": "fly", "wizards": "do magic", "griffins": "fly"}; // The function does not return anything. function funcMagicAction(doer) { elem.innerHTML += objMagic[doer]; } // Invoke the function. funcMagicAction("dragons"); // Prints "fly". </script> </html>
Since functions can be anonymous, it is possible to define the function and invoke it then and there! To illustrate, we provide the following example that defines an anonymous function that takes one argument, doer, and then prints the action based on the magicAction object. Once we have defined the function, we provide an argument within a pair of parenthesis ( as "("dragons")") at the end to indicate that we would like to invoke the function immediately.
<!doctype html> <html> <div id="idDiv"></div> <script type="text/javascript"> // Get a handle of the div element. var elem = document.getElementById("idDiv"); // Define an object to store name/action pairs for magic beings! var objMagic = {"dragons": "fly", "wizards": "do magic", "griffins": "fly"}; // Define an anonymous function and the invoke it. (function (doer) {elem.innerHTML += (objMagic[doer]);})("dragons"); // Prints "fly". </script> </html>
Needless to say, if the function does not accept any argument, then we can just provide a pair of empty parenthesis for the above example. In JavaScript programming, writing anonymous functions and invoking them immediately is a fairly common style.