A function literal
One of the most important concepts in JavaScript is that the functions are the primary unit of execution. Functions are the pieces where you will wrap all your code, hence they will give your programs a structure.
JavaScript functions are declared using a function literal.
Function literals are composed of the following four parts:
- The function keyword.
- An optional name that, if specified, must be a valid JavaScript identifier.
- A list of parameter names enclosed in parentheses. If there are no parameters to the function, you need to provide empty parentheses.
- The body of the function as a series of JavaScript statements enclosed in braces.
A function declaration
The following is a very trivial example to demonstrate all the components of a function declaration:
function add(a,b){ return a+b; } c = add(1,2); console.log(c); //prints 3
The declaration begins with a function
keyword followed by the function name. The function name is optional. If a function is not given a name, it is said to be anonymous. We will see how anonymous functions are used. The third part is the set of parameters of the function, wrapped in parentheses. Within the parentheses is a set of zero or more parameter names separated by commas. These names will be defined as variables in the function, and instead of being initialized to undefined, they will be initialized to the arguments supplied when the function is invoked. The fourth part is a set of statements wrapped in curly braces. These statements are the body of the function. They are executed when the function is invoked.
This method of function declaration is also known as function statement. When you declare functions like this, the content of the function is compiled and an object with the same name as the function is created.
Another way of function declaration is via function expressions:
var add = function(a,b){ return a+b; } c = add(1,2); console.log(c); //prints 3
Here, we are creating an anonymous function and assigning it to an add
variable; this variable is used to invoke the function as in the earlier example. One problem with this style of function declaration is that we cannot have recursive calls to this kind of function. Recursion is an elegant style of coding where the function calls itself. You can use named function expressions to solve this limitation. As an example, refer to the following function to compute the factorial of a given number, n
:
var facto = function factorial(n) { if (n <= 1) return 1; return n * factorial(n - 1); }; console.log(facto(3)); //prints 6
Here, instead of creating an anonymous function, you are creating a named function. Now, because the function has a name, it can call itself recursively.
Finally, you can create self-invoking function expressions (we will discuss them later):
(function sayHello() { console.log("hello!"); })();
Once defined, a function can be called in other JavaScript functions. After the function body is executed, the caller code (that executed the function) continues to execute. You can also pass a function as a parameter to another function:
function changeCase(val) { return val.toUpperCase(); } function demofunc(a, passfunction) { console.log(passfunction(a)); } demofunc("smallcase", changeCase);
In the preceding example, we are calling the demofunc()
function with two parameters. The first parameter is the string that we want to convert to uppercase and the second one is the function reference to the changeCase()
function. In demofunc()
, we call the changeCase()
function via its reference passed to the passfunction
argument. Here we are passing a function reference as an argument to another function. This powerful concept will be discussed in detail later in the book when we discuss callbacks.
A function may or may not return a value. In the previous examples, we saw that the add
function returned a value to the calling code. Apart from returning a value at the end of the function, calling return
explicitly allows you to conditionally return from a function:
var looper = function(x){ if (x%5===0) { return; } console.log(x) } for(var i=1;i<10;i++){ looper(i); }
This code snippet prints 1
, 2
, 3
, 4
, 6
, 7
, 8
, and 9
, and not 5. When the if (x%5===0)
condition is evaluated to true, the code simply returns from the function and the rest of the code is not executed.