A function is a container of code statements that can be invoked using the parentheses () operator. Parameters can be passed inside of the parentheses during invocation so that the statements in the function can access certain values when the function is invoked.

In the following code, we create two versions of an addNumbers function objectone using the new operator and another using the more common literal pattern. Both are expecting two parameters. In each case, we invoke the function, passing parameters in the parentheses () operator.

Sample: sample76.html

A function can be used to return a value, construct an object, or as a mechanism to simply run code. JavaScript has several uses for functions, but in its most basic form a function is simply a unique scope of executable statements.

Function() Parameters

The Function() constructor takes an indefinite number of parameters, but the last parameter expected by the Function() constructor is a string containing statements that comprise the body of the function. Any parameters passed to the constructor before the last will be available to the function being created. Its also possible to send multiple parameters as a comma-separated string.

In the following code, I contrast the usage of the Function() constructor with the more common patterns of instantiating a function object.

Sample: sample77.html

Directly leveraging the Function() constructor is not recommended or typically ever done because JavaScript will use eval() to parse the string containing the functions logic. Many consider eval() to be unnecessary overhead. If its in use, a flaw in the design of the code is highly possible.

Using the Function() constructor without the new keyword has the same effect as using only the constructor to create function objects (new Function('x','return x') vs. function(('x','return x')).

No closure is created when invoking the Function() constructor directly.

Function() Properties and Methods

The function object has the following properties (not including inherited properties and methods):

Properties (Function.prototype;):

Function Object Instance Properties and Methods

Function object instances have the following properties and methods (not including inherited properties and methods):

Instance Properties (var myFunction = function(x, y, z) {}; myFunction.length;):

Instance Methods (var myFunction = function(x, y, z) {}; myFunction.toString();):

Functions Always Return a Value

While its possible to create a function simply to execute code statements, its also very common for a function to return a value. In the following sample, we are returning a string from the sayHi function.

Sample: sample78.html

If a function does not specify a return value, undefined is returned. In the following sample, we call the yelp function which logs the string 'yelp' to the console without explicitly returning a value.

Sample: sample79.html

The concept to take away here is that all functions return a value, even if you do not explicitly provide a value to return. If you do not specify a value to return, the value returned is undefined.

Functions Are First-Class Citizens (Not Just Syntax, but Values)

In JavaScript, functions are objects. This means that a function can be stored in a variable, array, or object. Also, a function can be passed to and returned from a function. A function has properties because it is an object. All of these factors make functions first-class citizens in JavaScript.

Sample: sample80.html

It is crucial that you realize a function is an object, and thus a value. It can be passed around or augmented like any other expression in JavaScript.

Passing Parameters to a Function

Parameters are vehicles for passing values into the scope of a function when it is invoked. In the following sample we invoke addFunction(). Since we have predefined it to take two parameters, two added values become available within its scope.

Sample: sample81.html

In contrast to some other programming languages, it is perfectly legal in JavaScript to omit parameters even if the function has been defined to accept these arguments. The missing parameters are simply given the value undefined. Of course, by leaving out values for the parameters, the function might not work properly.

If you pass a function unexpected parameters (those not defined when the function was created), no error will occur. And it's possible to access these parameters from the arguments object, which is available to all functions.

this and arguments Values Are Available to All Functions

Inside the scope and body of all functions, the this and arguments values are available.

The arguments object is an array-like object containing all of the parameters being passed to the function. In the following code, even though we forgo specifying parameters when defining the function, we can rely on the arguments array passed to the function to access parameters if they are sent upon invocation.

Sample: sample82.html

The this keyword, passed to all functions, is a reference to the object that contains the function. As you might expect, functions contained within objects as properties (methods) can use this to gain a reference to the parent object. When a function is defined in the global scope, the value of this is the global object. Review the following code and make sure you understand what this is returning.

Sample: sample83.html

The arguments.callee Property

The arguments object has a property called callee, which is a reference to the function currently executing. This property can be used to reference the function from within the scope of the function (arguments.callee)a self-reference. In the following code, we use this property to gain a reference to the calling function.

Sample: sample84.html

This can be useful when a function needs to be called recursively.

The Function Instance length Property and arguments.length

The arguments object has a unique length property. While you might think this length property will give you the number of defined arguments, it actually gives the number of parameters sent to the function during invocation.

Sample: sample85.html

Using the length property of all Function() instances, we can actually grab the total number of parameters the function is expecting.

Sample: sample86.html

The arguments.length property was deprecated in JavaScript 1.4, but the number of arguments sent to a function can be accessed from the length property of the function object. Moving forward, you can get the length value by leveraging the callee property to first gain reference to the function being invoked (arguments.callee.length).

Redefining Function Parameters

A functions parameters can be redefined inside the function either directly, or by using the arguments array. Take a look at this code:

Sample: sample87.html

Notice that I can redefine the value of the bar parameter using the arguments index or by directly reassigning a new value to the parameter.

Return a Function Before It Is Done (Cancel Function Execution)

Functions can be cancelled at any time during invocation by using the return keyword with or without a value. In the following sample, we are canceling the add function if the parameters are undefined or not a number.

Sample: sample88.html

The concept to take away here is that you can cancel a function's execution by using the return keyword at any point in the execution of the function.

Defining a Function (Statement, Expression, or Constructor)

A function can be defined in three different ways: a function constructor, a function statement, or a function expression. In the following example, I demonstrate each variation.

Sample: sample89.html

Some have said that there is a fourth type of definition for functions, called the "named function expression." A named function expression is simply a function expression that also contains a name (e.g., var add = function add(x, y) {return x+y}).

Invoking a Function (Function, Method, Constructor, or call() and apply())

Functions are invoked using four different scenarios or patterns.

  • As a function
  • As a method
  • As a constructor
  • Using apply() or call()

In the following sample, we examine each of these invocation patterns.

Sample: sample90.html

Make sure you are aware of all four of the invocation patterns, as code you will encounter may contain any of them.

Anonymous Functions

An anonymous function is a function that is not given an identifier. Anonymous functions are mostly used for passing functions as a parameter to another function.

Sample: sample91.html

Self-Invoking Function Expression

A function expression (really any function except one created from the Function() constructor) can be immediately invoked after definition by using the parentheses operator. In the following sample, we create a sayWord() function expression and then immediately invoke the function. This is considered to be a self-invoking function.

Sample: sample92.html

Self-Invoking Anonymous Function Statements

Its possible to create an anonymous function statement that is self-invoked. This is called a self-invoking anonymous function. In the following sample, we create several anonymous functions that are immediately invoked.

Sample: sample93.html

According to the ECMAScript standard, the parentheses around the function (or anything that transforms the function into an expression) are required if the function is to be invoked immediately.

Functions Can Be Nested

Functions can be nested inside of other functions indefinitely. In the following code sample, we encapsulate the goo function inside of the bar function, which is inside of the foo function.

Sample: sample94.html

The simple concept here is that functions can be nested and there is no limit to how deep the nesting can go.

Remember, the value of this for nested functions will be the head object (the window object in a web browser) in JavaScript 1.5, ECMA-262, Edition 3.

Passing Functions to Functions and Returning Functions From Functions

As previously mentioned, functions are first-class citizens in JavaScript. And since a function is a value, and a function can be passed any sort of value, a function can be passed to a function. Functions that take and/or return other functions are sometimes called "higher-order functions.

In the following code, we are passing an anonymous function to the foo function which we then immediately return from the foo function. It is this anonymous function that the variable bar points to, since foo accepts and then returns the anonymous function.

Sample: sample95.html

So when bar is invoked, it invokes the anonymous function that was passed to the foo() function, which is then passed back from the foo() function and referenced from the bar variable. All this is to showcase the fact that functions can be passed around just like any other value.

Invoking Function Statements Before They Are Defined (aka Function Hoisting)

A function statement can be invoked during execution before its actual definition. This is a bit odd, but you should be aware of it so you can leverage it, or at least know what’s going on when you encounter it. In the following sample, I invoke the sayYo() and sum() function statements before they are defined.

Sample: sample96.html

This happens because before the code runs, function statements are interpreted and added to the execution stack/context. Make sure you are aware of this as you use function statements.

Functions defined as function expressions are not hoisted. Only function statements are hoisted.

A Function Can Call Itself (aka Recursion)

It’s perfectly legitimate for a function to call itself. In fact, this is often used in well-known coding patterns. In the code that follows, we kick off the countDownFrom function, which then calls itself via the function name countDownFrom. Essentially, this creates a loop that counts down from 5 to 0.

Sample: sample97.html

You should be aware that it’s natural for a function to invoke itself (aka recursion) or to do so repetitively.


Functions are one of the most used aspects of JavaScript, hopefully you now have a better understanding of how to use them.



Related Articles