JavaScript chain functions and function chaining in javascript usually mean one of three patterns: nested calls f(g(h(x))), fluent method chaining where each step returns the same object (often this) for dot syntax, or array pipelines such as filter → map → reduce for chaining js transforms on collections. The examples below are synchronous; for .then() and async/await pipelines, see promise chaining in JavaScript.
Tested on: Node.js v20.18.2. A short note after each snippet describes what you should see in the console.
Quick reference
Chaining is really about what each step returns: nested calls pass values, fluent APIs return this, and array methods return the next collection in the pipeline.
| Style | When it shines |
|---|---|
Nested f(g(x)) |
One-off, few steps |
pipe / compose |
Reusable pipelines, testing each step |
Fluent return this |
Mutable builders / counters |
| Array method chain | Data transforms on lists |
Nested calls — innermost first
Each wrapper runs after the value from the inner call is known:
function add(x) {
return x + 2;
}
function multiply(x) {
return x * x;
}
function subtract(x) {
return x - 3;
}
function stat(x, y) {
return (x + y / Math.PI) * Math.E;
}
let result = stat(subtract(multiply(add(5))), 4);
console.log(result);Evaluation: add(5) → 7, multiply(7) → 49 (here multiply squares its input), subtract(49) → 46, then stat(46, 4).
You should see one line like: 128.50198802684514.
Fluent method chaining — return this
For chain javascript on a single object, each method mutates or extends state and returns this so the next call has the same receiver.
Use normal function methods (or method shorthand) when you need this on the object—JavaScript arrow functions do not get their own this and break this pattern unless you return a fixed reference manually.
let obj = {
value: 1,
add: function (x) {
this.value += x;
return this;
},
multiply: function () {
this.value *= this.value;
return this;
},
subtract: function (x) {
this.value -= x;
return this;
},
};
let result = obj.add(5).multiply().subtract(3).value;
console.log(result);Steps: 1 + 5 = 6, 6 * 6 = 36, 36 - 3 = 33.
You should see one line like: 33.
filter → map → reduce — array pipelines
Array methods return new arrays or a folded value, so javascript chaining functions on collections is done by calling the next method on that return value. When map needs the element index, the callback’s second argument covers that—see JavaScript map with index.
const numbers = [11, 23, 83, 49, 50];
const sum = numbers
.filter((n) => n % 2 === 0)
.map((n) => n * 2)
.reduce((s, n) => s + n, 0);
console.log(sum);Even numbers: 50 → doubled 100 → sum 100.
You should see one line like: 100.
pipe and compose — reusable pipelines
Higher-order helpers fix the order of application—each step is a function passed as a value—so you can name and reuse pipelines instead of growing nested parentheses.
const add = (x) => x + 2;
const multiply = (x) => x * x;
const subtract = (x) => x - 3;
const pipe =
(...fns) =>
(x) =>
fns.reduce((v, f) => f(v), x);
const compose =
(...fns) =>
(x) =>
fns.reduceRight((v, f) => f(v), x);
console.log(pipe(add, multiply, subtract)(5));
console.log(compose(subtract, multiply, add)(5));pipe(add, multiply, subtract)(5) applies add, then multiply, then subtract (left to right in the list)—the same result as the nested call subtract(multiply(add(5))).
compose(subtract, multiply, add)(5) uses reduceRight so the last function in the list runs first on the value; here it also yields 46.
You should see 2 lines: 46, then 46.
Summary
Name the pattern you are using—nested calls, fluent builders, array pipelines, or pipe / compose—so the next reader knows which value flows to the next step.
- Nested
f(g(h(x)))evaluates innermost first; good for a few fixed steps. - Fluent APIs return
thisfrom each chainable method; avoid arrow methods whenthismust be the builder instance. filter/map/reducechain on arrays by using each method’s return value as the next receiver.piperuns the listed functions left to right;composeruns them right to left—pick the order that matches how you read the domain.
References
MDN guides for functions and array iteration—core references for js chain functions and collection pipelines.
- MDN: Functions guide
- MDN:
Array.prototype.filter() - MDN:
Array.prototype.map() - MDN:
Array.prototype.reduce()
Frequently Asked Questions
What is function chaining in javascript?
It usually means either nested calls f(g(h(x))) so each result feeds the next, or fluent method chaining where each method returns the same object (often this) so you can keep calling .method().method().
How is javascript chaining functions different on arrays?
Array methods like filter, map, and reduce return new arrays or a final value, so you chain by calling the next method on the returned array. That is a pipeline style of chaining js collections.
Why must methods return this for chain javascript fluent APIs?
The next call in the chain needs a receiver. Returning this passes the same object along. A terminal method often returns a plain value or a built object instead of this.
Can I use arrow functions for methods I want to chain on an object literal?
Arrow functions do not have their own this. Use normal methods or function properties so this refers to your object, and return this from each chainable step.
What is the difference between pipe and compose for javascript function chaining?
pipe(f,g,h)(x) runs left to right as h(g(f(x))). compose(f,g,h)(x) runs right to left as f(g(h(x))). Pick the order that matches how you read your domain steps.
Does nested function chaining short-circuit errors?
No. If an inner call throws, outer calls do not run. Use try/catch around the whole expression or validate inputs per step.
