JavaScript functions as arguments, and return values

The definition of lambdas is just anonymous functions that are passed as arguments to functions, or returned as results of function calls.

The lambda defines the function, but does not execute it. It is executed by the function it is passed to with arguments decided by that function.

Function as argument
Function as return value

Function as argument

The idea of using a function as an argument is used in the built-in objects of the JavaScript language itself. One example of this is the filter method of the Array object. The filter method's first argument; callback is a function that takes one argument. The callback function is invoked for each element in the Array in turn. If callback returns true, the element is included in the result, otherwise it is filtered out.

Here is an example:

main.js

if(!NSLambdas) {  
  var NSLambdas = {};
}

NSLambdas.filter = function() {  
  var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  var odd = numbers.filter(function(element) {
    return element % 2;
  });
  console.log(odd);
};

(function(){
  window.addEventListener("load", function() {
    NSLambdas.filter();
  });
}());

index.html

<!DOCTYPE html>  
<html>  
  <head>
    <title>Lambdas</title>
    <script src="main.js"></script> 
  </head>
  <body>
  </body>
</html>  

Loading the page will output the following to the console:
Filter

You can see the console in the Chrome browser by pressing Ctrl + Shift + J.

Function as return value

Returning a function as a result of a function call can also be useful. It doesn't seem like there are any examples of this in the language itself.

Instead of defining the callback function inline, we can make a function that returns the callback function to pass into the Array filter method.

It will look like this:

if(!NSLambdas) {  
  var NSLambdas = {};
}

NSLambdas.filterFactory = function() {  
  var that = {};
  that.odd = function(element) {
    return element % 2;
  };
  that.even = function(element) {
    return !that.odd(element);
  };
  return that;    
};

(function(){
  window.addEventListener("load", function() {
    var items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    var factory = NSLambdas.filterFactory();
    var even = items.filter(factory.even);
    console.log(even);
  });
}());

Loading the page will output the following to the console:

Factory

This pattern promotes code reuse. It also has the advantage of making the filterFactory directly testable.

Rule of thumb: Whenever you see a function that takes a function as argument, think about whether you can create a function to create that function.

I know... Just reading the statement above makes me a little dizzy too.