Functional Programing in JavaScript

, , …,

This page teaches you functional programing in JavaScript.

The programing techniques on this page are not JavaScript basics, but are not advanced “fancy tricks” neither. If you do any serious JavaScript programing, you have to know all of the techniques shown on this page.

JavaScript Function Techniques

Defining a Function

Here's how to define a function:

// defines a function
function f(n) {return n+1;};

Function without 「return」 returns 「undefined」

If you want your function to return a value, you must use the return statement with keyword return. A function without return value, when called, will return the builtin special value undefined. Example:

// function without return statement returns undefined
function f(n) {n;};

console.log(f(3));              // undefined

Pure Function (aka Anonymous Function, lambda)

You can define a function without naming it. Example:

// defines a function without naming it
function (n) {return n+1;};

Apply a Function to a Value

You can apply a function to value directly.

// apply a pure function to value directly
function (n) {return n+1;} (2);   // result value is 3

Function's Value is 「function」

A function definition has a value that represent the function. Its type is “function”.

console.log(
    typeof(
        function f() {return 1;}
    )
);                              // prints 「function」

Assign a Function to Variable

You can assign a function to a variable.

// assign a function to a variable
var f = function (n) {return n+1;};
console.log(f(2)); // prints 3

The above is effectively equivalent to this:

function f(n) {return n+1;};

Function Returning a Function

You can have a function return another function.

// function returning a function
function f(n) {
    return function (x) {return (n.toString() + " and " + x.toString() ); };
}

console.log (f(2) (7)); // prints 「2 and 7」

So, for example, you can define a function f(n) that returns a function g(x) that computes nth power of x.

// function returning a function
function f(n) {
    return function (x) {return Math.pow(x,n); };
}

console.log (f(2) (7)); // prints 49

In the above, we first call f(2), the result is a function that computes x^2. Then, we give this function a argument of 7, so the result is 49.

Recursion

Function can call itself. Here's a example of factorial.

function f(n) {
    if (n < 0)  { return -1; }
    if (n == 0) { return 1; } else return (n * f(n - 1));
}

console.log(f(4)); // prints 24. (it's 4×3×2×1)

Function Composition

Because all the above features, JavaScript has some ability to do advanced functional programing. For example, we can define a function (say, simpleFunctionCompose), that takes 2 arguments, each is a function (say, f and g), and simpleFunctionCompose returns a new function whose behavior is equivalent to f(g(x)).

// function composition

// takes two single value functions f(x) and g(x) and returns a
// function that computes f(g(x))
function simpleFunctionCompose(f, g) {
    return function (n) { return f(g(n)); };
}

// test
function h(n) { return n+1;}
function i(n) { return n*2;}

console.log(simpleFunctionCompose(h,i)(3)); // prints 7

A Practical Example: Passing Parameter to a Event Handler

Here's a practical Example. Suppose we have this function that colors a HTML element red:

function ff (myobj) {
    myobj.style.color="red";
}

Now, we want to assign this to a event, so that when mouse hovers over a HTML element, it becomes red. We do this:

var myElements = document.getElementsByClassName("u");

for (var i = 0; i < myElements.length; i++) {
  myElements[i].onmouseover = ff(myElements[i]);
}

When the event happens, our function gets called.

But the above won't work, because the right hand side needs to be a function (the value should be of type function).

The code above evaluates ff(myElements[i]), which makes all the elements red, and returns undefined. When a event happens, it invokes undefined. This is not what we want.

To solve this problem, we need the right hand side to return a function. But if we do this: myElements[i].onmouseover = ff; that won't work neither because our function “ff” needs a argument.

What we can do, is to write a function that takes the argument, and this function returns our function that calls our function with the argument. Like this:

function ff (myobj) {
    myobj.style.color="red";
}

function createHandler( myobj ) {
    return function() {ff(myobj); };
}

var xx = document.getElementsByClassName("u");

for (var ii = 0; ii < xx.length; ii++) {
    xx[ii].onmouseover = createHandler( xx[ii] );
}

Normally, the createHandler is writte inline, like this:

xx[ii].onmouseover = function () { return function() {ff(xx[ii]); }; }

Thanks to Sirko for help. Source stackoverflow.com.

Variable Scope: Function Level vs Block Level

JavaScript Variable Scope: Function Level vs Block Level

Variable & Function Declaration Order: Name Hoisting

JavaScript: Variable & Function Declaration Order: Name Hoisting

Function Constructor

JavaScript Function Constructor

Closure, and Function with State

JavaScript: Closure, and Function with State

blog comments powered by Disqus