Chaining

Enables calling multiple methods on a single object.



Usage in JavaScript:
high


Fundamentals


The Chaining Pattern enables calling multiple methods on a single object by stringing them together in a single statement, just like a chain. The result is a more concise coding style. Here is an example:

var obj = object.method1("arg1").method2("arg2").method3("arg3");

The equivalent code, without chaining requires several lines of code with intermediate variables. It would look like this:

var obj1 = object.method1("arg1");
var obj2 = obj1.method2("arg2");
var obj = obj2.method3("arg3");

How do you make methods chainable? Actually, it is simple: just return the internal this variable, i.e. the current object the method is working on; like so:

function func(arg) {

    // do something ...

    return this;
}

Let's look at an example:

function Calculator(start) {
    
    var total = start || 0;

    this.add = function (x) { total +=x; return this; };
    this.sub = function (x) { total -=x; return this; };
    this.mul = function (x) { total *=x; return this; };
    this.div = function (x) { total /=x; return this; };

    this.get = function () { return total; };
}


Notice that each calculator operation returns this. This allows us to chain the operations together in a single statement.

var calculator = new Calculator(10).add(8).div(2).mul(4).sub(30).add(100);   

alert("value = " + calculator.get());    // => value = 106

Run

When a method does not have an obvious return value you should consider returning this. If it is never used it will be harmless, but it will allow clients of the method to combine it together with other methods in a single concise (i.e. chained) statement.

A disadvantage of chaining is that it makes debugging harder. If an error occurs in any of your chained methods the debugger will inform you of the line in which the error occurs but not the method in which it failed. To dig deeper, you may need to unchain and create temporary variable assignments for each method to be able to pinpoint the failing method.

Some developers refer to chaining as fluent interfaces, which is just another term for the Chaining Pattern.

Chaining is a widely used pattern. The most popular JavaScript library, which is jQuery, uses it extensively. Consider the following HTML markup and jQuery code:

<div id="thediv">
   <table>
      <tr><td class="col"></td><tr>
      <tr><td class="col"><td></tr>
    <table>
</div>

$("#thediv")
    .find("table .col")
    .removeClass(".col")
    .css("background", "purple")
    .css("color", "white")
    .append("purple here");


This is an example of jQuery chaining. In a single statement the jQuery selector selects all divs on the page; then for each div it finds tables with elements that have class='col'. Next it changes their background to purple, their color to white, and appends text to the element. If you run the code you will see the results above.

This jQuery example demonstrates that with chaining you can write amazingly compact and concise code. Another benefit to jQuery is that the selector, i.e. the $("div") part in the above code, is executed only once. This is significant as the selector is almost always the slowest part of a jQuery statement because it needs to search the entire page.

Adding custom chainable methods to jQuery is remarkably easy. Of course, it must return this, which in jQuery is the element that it just worked on. In the code below we are adding a custom turnBlue method to jQuery:

$.fn.turnBlue = function () {
     return $(this).css("background", "blue");
};

You can now include turnBlue in any jQuery chaining statement. Here is an example:

<div id="myDiv" style="background:yellow;width:50px;height:50px;"></div>

$("#myDiv").css("border", "solid 10px red")
           .turnBlue()
           .animate({ "width": "400px" }, 1000);



  Module