Hi there,

I'm a software engineer living in Victoria BC, Canada. I love building things. I work for sendwithus. Most of my days are spent writing Nodejs apps and REST APIs. I have a few side projects Platform PixelsTo ReadCode Replay, and Simple Blog (the thing you're looking at) 

Method Chaining in JavaScript

Method chaining is a common pattern in the JavaScript world. This tutorial will provide a brief explanation of what method chaining is, give a real world example of how jQuery uses method chaining, and teach you how to add method chaining to your own classes. Let's get started.

What is Method Chaining?

Method chaining is a technique that can be used to simplify code in scenarios that involve calling multiple functions on the same object consecutively. This is an example of how you can use method chaining when using jQuery.


/** Example of method chaining in jQuery */


//////////////////////////
// WITHOUT METHOD CHAINING

var $div = $('#my-div');         // assign to var

$div.css('background', 'blue');  // set BG
$div.height(100);                // set height
$div.fadeIn(200);                // show element


///////////////////////
// WITH METHOD CHAINING

$('#my-div').css('background', 'blue').height(100).fadeIn(200);

// often broken to multiple lines:
$('#my-div')
  .css('background', 'blue')
  .height(100)
  .fadeIn(200);

As you can see, using method chaining can tidy up code quite a bit, however some developers dislike the visual style of method chaining and choose not to use it.

Understanding Method Chaining

For our example, we will define a custom class with a few methods to call. Let's create a Kitten class:



// define the class
var Kitten = function() {
  this.name = 'Garfield';
  this.color = 'brown';
  this.gender = 'male';
};

Kitten.prototype.setName = function(name) {
  this.name = name;
};

Kitten.prototype.setColor = function(color) {
  this.color = color;
};

Kitten.prototype.setGender = function(gender) {
  this.gender = gender;
};

Kitten.prototype.save = function() {
  console.log(
    'saving ' + this.name + ', the ' +
    this.color + ' ' + this.gender + ' kitten...'
  );

  // save to database here...
};

Now, let's instantiate a kitten object from our class and call its methods.


var bob = new Kitten();

bob.setName('Bob');
bob.setColor('black');
bob.setGender('male');

bob.save();

// OUTPUT:
// > saving Bob, the black male kitten...

Wouldn't it be better if we could get rid of some of this repetition? Method chaining would be perfect for this. The only problem is that currently this won't work. Here is why:


var bob = new Kitten();

bob.setName('Bob').setColor('black');

// ERROR:
// > Uncaught TypeError: Cannot call method 'setColor' of undefined

To better understand why this doesn't work, we will rearrange the code above slightly.


var bob = new Kitten();

var tmp = bob.setName('Bob');
tmp.setColor('black');

// ERROR:
// > Uncaught TypeError: Cannot call method 'setColor' of undefined

This returns the same error. This is because the setName() function doesn't return a value, so tmp is assigned the value of undefined. The typical way to enable method chaining is to return the current object at the end of every function.

Implementing Method Chaining

Let's rewrite the Kitten class with the ability to chain methods.


// define the class
var Kitten = function() {
  this.name = 'Garfield';
  this.color = 'brown';
  this.gender = 'male';
};

Kitten.prototype.setName = function(name) {
  this.name = name;
  return this;
};

Kitten.prototype.setColor = function(color) {
  this.color = color;
  return this;
};

Kitten.prototype.setGender = function(gender) {
  this.gender = gender;
  return this;
};

Kitten.prototype.save = function() {
  console.log(
    'saving ' + this.name + ', the ' +
    this.color + ' ' + this.gender + ' kitten...'
  );

  // save to database here...

  return this;
};

Now, if we rerun the previous snippet, the variable tmp will reference the same object as the variable bob, like so:


var bob = new Kitten();

var tmp = bob.setName('Bob');
tmp.setColor('black');

console.log(tmp === bob);

// OUTPUT:
// > true

To shorten this even more, we do not even need to create the variable bob. Here are two examples with and without method chaining on our new class:


///////////////////
// WITHOUT CHAINING

var bob = new Kitten();

bob.setName('Bob');
bob.setColor('black');
bob.setGender('male');

bob.save();

// OUTPUT:
// > saving Bob, the black male kitten...


///////////////////
// WITH CHAINING

new Kitten()
  .setName('Bob')
  .setColor('black')
  .setGender('male')
  .save();

// OUTPUT:
// > saving Bob, the black male kitten...

By using method chaining we end up with much cleaner code that is easier to understand.

Conclusion

That's it! Method chaining can be a very useful technique to have in your bag of programming tools. If you have any questions, let me know in the comments below.


Martin Mauchauffée and Manu Delgado Diaz pointed out that this is also known as the Fluent Interface pattern.

Юрий Тарабанько came up with a great way to automate the addition of return this;. Check out his chainify() function in this Fiddle

Opinions

 Nov 14, 2013

Lal Thomas writes:


Nice tip...

 Nov 14, 2013

Rajendrasinh parmar writes:


Nice article..


it's really helpful.!
thanks :)

 Nov 14, 2013

Gregory writes:


I'm glad you two found it helpful.

 Nov 14, 2013

Vittorio writes:


Nice article. I happen to have written a library for method chaining. It also works with promises:

http://www.vittoriozaccaria.net/chained/

Have a look and tell me what you think ;)

 Nov 14, 2013

Gregory writes:


@Vittorio That looks pretty awesome! It is a little too 'magical' for my liking, but I can see it being really useful for certain situations.

 Dec 10, 2013

Ankit writes:


Really nice article...well explained!!

 Feb 28, 2014

Aman Gupta writes:


Awesome.. nice.. :)

 Feb 28, 2014

Aman Gupta writes:


I have 1 doubt.. just asking here.. does chaining forward current data scope to the next level ? I mean .method1("s").method2("o").method3("m").method4("e") will give me "some" ? my context is toward the promises. how can we implement promises here, so that data available from method 1 should forward to method 2 once it done and so on... Thanks :)

 Feb 28, 2014

Gregory writes:


@Aman Gupta The solution I've provided here will not give you what you want. Scope will not be forwarded between function calls like that without storing it explicitly in some way.

 Mar 24, 2014

Junior enrique Ramos Espinoza writes:


Thanks man this information served me well, especially since I was looking for help and could not find it in Spanish, now if that is chaining aclaraste clearing all my doubts. Greetings from Peru

 Apr 6, 2014

Shibu Alexis writes:


Gregory, first of all I'm amazed about your writing skill. Very well explained with cuts and pieces.

I have a question.

$("div")//returns multiple elements.
.height(500)// each elements it sets the height.
.width(500)// each elements it set the width.

How many loop? Isn't it inefficient?

 Apr 9, 2014

Raj writes:


Nice One!! Wish there was explanation on few more patterns like Module, Sandbox etc..

 Apr 9, 2014

Gregory writes:


@Raj, that's a great idea. I'll definitely think about doing some more explanations.

 Apr 12, 2014

lolo writes:


cool, thanks

 Apr 15, 2014

Carlos Menezes writes:


Perfect! Thanks for sharing this information! Really useful!

 Apr 29, 2014

Richa writes:


Very good article. Very easy to undersatnd

 May 31, 2014

Lenin Sanchez writes:


Great, simple & clear!
Thanks :D

 Jun 3, 2014

jogo writes:


Simply and very well explained! Thanks.

 Jun 12, 2014

mam-p writes:


Super good explanation!!! Thx!

 Jul 20, 2014

Rehaan writes:


Great article, thanks a lot!!

 Jul 22, 2014

Vijay Balakrishnan writes:


Simple and well explained


Leave Another