Method Chaining in JavaScript
3 minute read
Are you still a JavaScript padawan learner? Then this post is for you. Maybe you’re still going over the basics of JavaScript, learning how to define functions, how objects work, and some of the other baby steps. And maybe you’ve toyed around with that semi-well known library for querying the DOM (and for doing wayyyy too many other things, IMO), le jQuery. If you have or if you’ve tried out another library, you’ve likely seen something like this:
myLib.doSomething().thenDoSomethingElse();
Or you might have learned about method chaining for something like array transformation:
anArray
.filter((element) => element === "foobar")
.map((element) => element.aProperty);
If you haven’t seen this or are writing all your method invocations out on separate lines, it’s time to consider method-chaining. It can sometimes make your code much more easy to read. Consider: This:
const aModule = require('something');
const.doMethod();
const.doAnotherMethod();
const.doYetAnotherMethod();
const.reallyWeAreCallingSomethingElse();
const.done();
…could be this!
const aModule = require('something');
// these operations are meaningfully grouped
const.doMethod().doAnotherMethod().doYetAnotherMethod();
// ... some other operations ...
aModule.reallyWeAreCallingSomethingElse().done();
// ++readability!
##Considerations First, there’s the small bit of extra space your files will take up. This isn’ the primary gain you get, but it’s still something. Remember that you shouldn’t be optimizing first, whether it’s in terms of file size or performance or other considerations. During (good) refactoring is the time and place where you can focus on getting rid of cruft and slimming things down.
The more important gain realized by using method chaining is readability and lowered mental load. Even though reading const
four times isn’t a huge mental drain, it’s unnecessary. You can easily omit those repetitions. You need to consider that it’s not just these few lines you or someone else is likely to read, but thousands of other lines of code. And if every single file duplicates code, you’re going to be wasting mental energy.
Now, a caveat: there are plenty of times when an intermediate operation in between method calls means you’ll need to not chain methods together. Not a problem at all! You see, the big idea is to write appropriate and elegant code, so when you really need to separate calls out, do so!
It’s All About This
So, how do you allow your custom objects to use method chaining? It’s all about this
. The this
binding in JavaScript is provided as the ‘execution context’ for a given function. There are at least four different general ways that this
takes on value in JavaScript, but it’s really all about context and the call-site for a function.
So, how do you make the execution context of a method available to the next method call so it can be chained? One general approach is to just return this
. That way, you can set up the next method call so it can execute in the same context as it’s predecessor.
const chainModule = (() => {
const privateValue = "private";
function privateMethod() {
console.log("I am a private method");
}
return {
publicValue: "public",
publicMethod() {
privateMethod();
console.log("public method called!");
return this;
},
exposeprivateValue() {
console.log(privateValue);
return this;
},
};
})();
chainModule.publicMethod().exposeprivateValue();
This isn’t a magical fix for all your code — you need to be extremely wary of accidentally losing your this
binding to an implicit global and there are other considerations to be had. But at the very least this should enable you to start writing more fluent APIs in your npm
modules and elsewhere!
Happy coding.
Related:
- A Guide to the React Ecosystem
- 50% off React in Action Today
- A Conceptual Introduction to React Components
- I'm writing a book about React!
- Type Inspection In Go
- Testing React Components with Enzyme and Mocha
- Start Simply, Simply Start
- Using Event Emitter in Node.js
- React Native: Quick Start and Including Images
- New NPM Module: Favorites
- Npm Modules I can't live without (pt. 2)
- Running Node.js Apps in Production
- Server-Side Rendering with React and React-Router
- Installing iojs and Node.js Together
- Get Functional