18

So... messing around in JavaScript with an idea that's new to me, having methods of an Object return the Object of which they are methods; this then leads to chainability. My question, then: how can this be useful? I threw this together to test the fundamental workings:

<script>
MathChain = function()
 {
    this.pass = function()
     {
        this.multiply = eval(arguments.join('*'));
        this.add = eval(arguments.join('+'));
        return this;
     }
 }

m = new MathChain().pass(5, 10, 20).multiply; // 1000
a = new MathChain().pass(5, 10, 20).add;      // 35
</script>

That's obviously not a viciously efficient instance in which one would use this concept, so could you point me to something that does do so properly (aside from jQuery, please)?

Grace Note
  • 3,205
  • 4
  • 35
  • 55
Hexagon Theory
  • 43,627
  • 5
  • 26
  • 30

9 Answers9

25

Well, here is a not very real-world applicable example, but I think you'll get the idea. If allows you to do a number of different operations on an object, and provides convenience.

var truck = function() {

    this.turnLeft = function {

       // turn left
       return this;

    }

    this.turnRight = function {

       // turn right
       return this;

    }

    this.goReallyFast = function {

       // go fast!
       return this;

    }

};

// My get-away plan
var myTruck = new truck();
myTruck.turnLeft().turnRight().goReallyFast();
jonstjohn
  • 59,650
  • 8
  • 43
  • 55
  • Heh, I like it; it definitely demonstrates a potential use case very well. Um... no real-world usage then outside of how it's implemented in various libraries? – Hexagon Theory Mar 02 '09 at 18:59
  • Hmmm, I think I understand what you're getting at. Are you getting at the efficiency question? I've always seen it as a matter of convenience. I know some people think that chaining is less readable than having each method on its own line. – jonstjohn Mar 02 '09 at 19:01
  • @jonstjohn, I would like to know pros and cons for chaining? – Manish Sapkal Dec 31 '13 at 07:58
  • Remember that `this` will refer to `window` if you don't instantiate objects but use modules (e.g. `RequireJS`) in stead. Define `var self = this` and use `self` to keep modules from overwriting each other. – Redsandro Mar 12 '14 at 01:31
8

Fluent interface - http://en.wikipedia.org/wiki/Fluent_interface

Yea I think it could be very useful but like any design pattern should only be used when needed

Edit: here is twitter client api in c# using a fluent interface - http://code.google.com/p/tweetsharp/

dfasdljkhfaskldjhfasklhf
  • 1,162
  • 2
  • 10
  • 18
8

For a very different (non-OO) example, chaining is somewhat analogous to Unix pipelines. Each step of a Unix pipe returns the full (modified) content, suitable for sending on to the next step:

cat file1 file2 | sort -n | awk '{print $2}' | sed 's/@/ at /g'
Anirvan
  • 6,214
  • 5
  • 39
  • 53
6

One example where it's useful is with a slight variation on your problem — instead of returning the same object, you design the object to be immutable. Then your functions will all return a new instance of the same type, but with the properties already set appropriately.

This has many practical applications, especially in the realm of functional programming.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • Hm... would that be return this.clone(), then? – Hexagon Theory Mar 02 '09 at 19:10
  • um... sort of, but I'm not sure you understand that concept yet. It's okay: immutable objects aren't easy. Look into .Net's String class for good example to get started. – Joel Coehoorn Mar 02 '09 at 19:19
  • This is a very interesting point that is initially hidden to beginners in programming. returning an object verss a new object is sometimes un-apparent. The main problem is that if you don't make new objects, sometimes this leads to handles pointing to the same object, and newbs will be confused when both "variables" change when they only modified one variable. – trusktr Mar 19 '11 at 07:05
3

I found this question while searching for a general solution to making methods chainable, after they are defined. Here's what I came up with. I am a JavaScript neophyte; buyer beware.

makeChainable = function() {
    var receiver = arguments[0]
    for (var i = 1; i < arguments.length; i++) {
        functionName = arguments[i];
        (function() {
            wrapped = receiver[functionName];
            receiver[functionName] = function() {
                wrapped.apply(receiver, arguments);
                return receiver;
            }
        })();
    }
}

daisy = {
    name: 'Daisy',
    moo:  function() { console.log(this.name + " moos!") }
}

makeChainable(daisy, 'moo');
daisy.moo().moo().moo();
sheldonh
  • 2,684
  • 24
  • 31
3

While it doesn't work in the same way as your example (TBH I've never seen it done that way before), jquery considers "chaining" to be very useful, and jquery is pretty much the yardstick these days when it comes to JS web frameworks... so yeah :-)

Orion Edwards
  • 121,657
  • 64
  • 239
  • 328
1

In JavaScript this comes up all the time when navigating the DOM. In particular when trying to wade your way through a bunch of elements that don't have ids.

For example there was a question on SO regarding finding the first element of a table. It can involve a lot of loops or chained commands.

Community
  • 1
  • 1
Paulo
  • 4,275
  • 2
  • 20
  • 20
0

JavaScript chaining can be very useful if you want to preform a series of actions on a single object. I agree with Michael Luton below, chaining should be handled with care. If you add one or two chained methods onto an object that is still readable. If you start adding four, five, or even nine, then your code becomes harder not only to read but to maintain.

Lark
  • 4,654
  • 7
  • 33
  • 34
-2

All the kids love chaining. However, in my experience it should be used with care since it can decrease the readability of the code. In other words, do what makes sense to you and can be easily understood by other programmers who have a basic familiarity with the concept..

  • 8
    I perosonally don't think it messes up readability if the method names are named in a nice manner. `car.turnLeft().turnRight().goStraight().stop();` doesn't seem hard to read to me. – trusktr Mar 19 '11 at 07:07
  • Chaining is a way to improve readability. Typically, developers think something is 'unreadable' when seeing something new because they are simply unfamiliar with it. – E10 Aug 23 '16 at 20:49