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.
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; arrow methods 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.
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 so you can name and reuse steps 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()
