Chaining - Fluent Interfaces In JavaScript
Written by Ian Elliot   
Friday, 23 February 2018
Article Index
Chaining - Fluent Interfaces In JavaScript
Singleton Chaining
Initialization

One of jQuery's attractive features is the way that you can build up chains of commands that look almost like the way you would use a language. This is more generally called a "Fluent Interface" and it isn't difficult to implement in JavaScript.

JavaScript Jems
Patterns & Practice

JavaScriptJems

Contents

  1. JavaScript Patterns 
    Why JavaScript is a Jem
  2. Objects with Values in JavaScript*
  3. Private Functions In JavaScript
  4. Chaining - Fluent Interfaces In JavaScript*
  5. Active Logic, Truthy and Falsey*
  6. The Confusing Comma In JavaScript*
  7. Self Modifying Code*
  8. Lambda expressions
  9. Meta Programming Using Proxy
  10. Master JavaScript Regular Expressions
  11. The Function Approach To Programming

*= recently revised.

<ASIN:1871962579>

<ASIN:1871962560>

<ASIN:1871962501>

<ASIN:1871962528>

The idea of a fluent interface was first coined by Eric Evans and Martin Fowler to express the idea of an object- oriented API. The technique uses method chaining, but if you want to call it a fluent interface it also has to have the characteristics of a domain specific language. Put simply, the way that the methods chain together has to express natural sets of operations. Ideally the chains of methods should read as if you were writing a tiny program with verbs and modifiers. 

First let's take a look at the mechanism of chaining.

In what follows don't worry to much about why you would want to do things. Concentrate instead on how they work.

The reasons and advantages of chaining and fluent interfaces will become clear later.

General Chaining

Chaining is where you call one function after another. For example:

function1().function2().function3()
 and so on...

It is usual, but not necessary, for the first function to be a method belonging to a particular object.

myObject.function1().function2().function3()
 and so on...

The object version of the chaining is the common idiom in other languages where functions aren't first class objects. In JavaScript, however, functions are first class objects and this makes the first form of chaining perfectly reasonable.

When you first see something like this, you can't help but wonder why it all works. Indeed, it doesn't work unless you arrange for the functions to fit together.

The principle of chaining is that each function has to return an object, which supports the next function in the chain as a method.

This is all there is to function chaining - it's simple but it is easy to become confused in real cases.

Take for example the chain:

function1().function2().function3()

For this to work function1 has to return an object which has function2 as a method. For simplicity, suppose obj2 has function2 as a method and obj3 has function3 as a method. First we need to define function1:

function1 = function(){
                        alert("function 1");
                        return obj2;
                      }

As promised, this returns obj2 which is defined as:

var obj2 = {

            function2: function () {
                        alert("function 2");
                        return  obj3;
            }
           };

which, again as promised, returns obj3 which is defined as:

var obj3 = {

            function3: function () {
                        alert("function 3");
                        return obj3;
                       }
           };

With these definitions you can now write:

function1().function2().function3();

and when you run the program you will see three alert boxes announcing function1, function2 and function3 in turn.

Of course, in practice the functions could have parameters and the objects could be generated by constructor functions requiring that we use new to create a new instance of each object to return.

Notice that it is the object returned by each function that gives the next function in the chain its context.

That is, you can determine exactly what function is called by the object you return. That is not only is this set to the object you have returned but the function that is used depends on the object you return.

For example, if the function was a search operation, then the display function called next could be automatically varied according to the type of object returned by the search. That is you call .display but the function you get depends on the object returned. This is a sort of natural polymorphism that all dynamically typed languages have.

Also notice that if you want to define function1 as a method of obj1 then this works, but now you have to start the chain with obj1:

obj1.function1().function2().function3();

This is all there is to function chaining and it all depends on each function returning an object which has the next function among its methods.

However, this isn't the most common way that function chaining is used.



Last Updated ( Thursday, 13 June 2019 )