Chaining functions in Javascript

One of the coolest features of jQuery is the ability to chain functions. The output of a function is the calling object. So instead of writing:

var a = $("<div></div>");
a.appendTo($("#id"));
a.hide();

... I can instead write:

$("<div></div>").appendTo($("#id")).hide();

A reasonable number of predefined Javascript functions can be used this way. I make extensive use of it with the String.replace function.

But where this feature is not available, you an create it in a fairly unobstrusive way. Just add this code to your script:

Function.prototype.chain = function() {
     var that = this;
     return function() {
         // New function runs the old function
         var retVal = that.apply(this, arguments);
         // Returns "this" if old function returned nothing
         if (typeof retVal == "undefined") { return this; }
 		// else returns old value
         else { return retVal; }
     }
};
var chain = function(obj) {
 	for (var fn in obj) {
 		if (typeof obj[fn] == "function") {
 		    obj[fn] = obj[fn].chain();
 		}
     }
 	return obj;
}

Now, chain(object) returns the same object, with all its functions replaced with chainable versions.

What's the use? Well, take the Google AJAX search API. Normally, to search for the top 8 "Harry Potter" PDFs on esnips.com, I'd have to do:

var searcher = new google.search.WebSearch();
searcher.setQueryAddition("filetype:PDF");
searcher.setResultSetSize(google.search.Search.LARGE_RESULTSET);
searcher.setSiteRestriction("esnips.com");
searcher.setSearchCompleteCallback(onSearch);
searcher.execute("Harry Potter");

Instead, I can now do this:

chain(new google.search.WebSearch())
     .setQueryAddition("filetype:PDF")
     .setResultSetSize(google.search.Search.LARGE_RESULTSET)
     .setSiteRestriction("esnips.com")
     .setSearchCompleteCallback(onSearch)
     .execute("Harry Potter");

(On the whole, it's probably not worth the effort. Somehow, I just like code that looks like this.)

Written on 18 Feb 2008

Comments


(not shared, not spammed)


S Anand, Infosys Consulting, London UK. +44 7957 440 260