Harnessing the power of the Function Object
The JavaScript language can operate equally well within many of the major programming paradigms. The first programming model most students learn is Procedural Programming; so called because procedures (functions) are used to group similar functionality. JavaScript also supports most of the features of the Object-Oriented (OO) model, such as encapsulation, modularity, polymorphism and inheritance. Perhaps not a pure OO language like Java, the proliferation of JavaScript Frameworks in recent years, as well as the inclusion of new functionality in later versions of JavaScript, have brought the language closer to true OO style. In this article, we explore the Function object and learn about its role in a lesser known style of coding called Functional Programming. Our specific area of focus is the Functional Programming concept of using Higher Order functions to improve code modularity. Ironically, JavaScript might be the most widely deployed Functional Programming language in use today, but most people are unaware of this fact. That's a shame, because the Functional Programming style is one of our best allies in writing well-structured and modularized code.
Functional Programming: What It's All About
Functional Programming emphasizes the evaluation of expressions rather than the execution of commands. Tracing back to calculus mathematics, the main goal of Functional Programming is to prevent the inadvertent changing of already calculated values. As developers know, the most likely cause of accidental variable modifications are functions that have access to global objects. The reason accessing of global variables by multiple functions is inherently dangerous is that changing a global variable in part of a program can have unexpected effects in another part. Functional programming isn't a replacement for Object-Oriented and Pricedural/Imperative styles; each has a place in Web development. Examples of Functional Programming languages include Scheme, Erlang and Haskell.
Higher Order Functions
A function becomes a Higher Order function when it treats other functions as values. JavaScript is well suited for this type of programming because functions are actually a Function object type. Observe the following two functions:
- You can pass functions to other functions.
- Functions can return another function.
- Functions have scope, just like any other variable.
Have a look at the following code and see how functions can be utilized in Higher Order programming:
In the above example, the testFor()
function accepts another function as an
argument and applies it to each of the passed function's arguments until it
returns true
. If none of the function calls return true
, the function exits
without returning anything. This will be evaluated as undefined
by any subsequent
tests and interpreted as false
. Another trait of Higher Order functions is the
returning of another function. This is exactly what happens here, since the testFor()
function doesn't return the results of the passed function, but another
function which contains the passed function. The returned function is
stored in the testForEvenNumbers
variable and subsequently called like
any other function.
We can further incorporate Functional Programming into our testFor()
function
by using some of the new JavaScript 1.6 map()
and indexOf() Array
methods. The
map()
method takes a function as a parameter and applies it to each element in
an array. The indexOf()
function searches through an array and returns the index
of the first element that contains the object we're looking for. A search
that fails to turn up the object in question returns an index of -1
. It accepts
the object we're seeking, as well as an optional element index. The only problem is the function's arguments
property isn't
an array. Before calling map()
and indexOf()
, we need to convert the arguments
into a proper Array
object. This is done by applying the Array
's prototype slice()
method. From there, we can chain the functions together by mapping the
passed function (fn
) to all the elements in the arguments
array and then calling
indexOf()
against the returned values, searching for the true
boolean value:
This is a powerful way of writing code because it leverages library functions that are well documented and tested, thus requiring less writing and testing on our part.