The following is a function which returns the chainable version of a function:


Function.prototype.chain = function() {
  var me = this;
  return function() {
    var ret = me.apply(this, arguments);
    return ret === undefined ? this : ret;
  }
};

Here is an example of how to define a pseudo-class which uses this chaining method:


function Person(firstName, lastName) {
  this._firstName = firstName;
  this._lastName = lastName;
}

Person.prototype.firstName = (function(firstName) {
  if(firstName)
    this._firstName = firstName;
  else
    return this._firstName;
}).chain();

Person.prototype.lastName = (function(lastName) {
  if(lastName)
    this._lastName = lastName;
  else
    return this._lastName;
}).chain();

Person.prototype.fullName = function() {
  return this._firstName + " " + this._lastName;
};

Here is an example which shows that the chaining works as intended:


// Create my person object as "Kris East" and display this faulty name.
var author = new Person("Kris", "East");
alert(author.fullName());

// Prove that first name getter works:  Kris
alert(author.firstName());

// Fix my name and then display it:  Chris West
alert(author.lastName("West").firstName("Chris").fullName());

// Prove that last name getter works:  West
alert(author.lastName());

2 Comments

Framp · August 3, 2013 at 4:33 PM

Am I missing something?

If you replace:
}).chain();
With:
return this; })
You’ll get the same result

JavaScript – Object.prototype.each() | Chris West's Blog · February 27, 2013 at 12:01 AM

[…] functions, if they don’t return anything, they really should return the object itself (snippet to make functions chainable). That is one of the many things John Resig did right in […]

Leave a Reply

Your email address will not be published. Required fields are marked *