Reputation: 1273
This came to may mind over the weekend and I was curious to know exactly what is happening when one chains methods together like the below code:
const posts = [{}, {}, {}, ...]
posts
.filter(({ node }) => node.fields.slug !== '/about/')
.reverse()
.slice(0, 5)
Each of the Array.prototype
methods returns an array after transforming the data in some fashion. filter
& slice
are both returning copies of the original array with the prescribed transformation present. What I am curious to know is if JavaScript is performing some internal piping like I would see in elixir
. Each method requires an array to work, but not necessarily as an argument, I think.
I don't believe the above is similar to. I know that the first arg must be whatever is returned from the prior operation for the pipe operator to work in elixir
:
posts
|> filter(({ node }) => node.fields.slug !== '/about/')
|> reverse()
|> slice(0,5)
Wasn't sure where to look to better understand this so if you can point me in the right direction I'll go read up on it. I was just curious to know, thanks so much for the information.
Upvotes: 3
Views: 1640
Reputation: 2855
It's nothing more complicated than returning either this
or some other new object. A simple example would be:
function Num(val) { // Num contructor
this.val = val;
};
Num.prototype.increment = function () {
this.val++;
return this;
}
Num.prototype.decrement = function () {
this.val--;
return this;
}
Num.prototype.getVal = function(){
return this.val;
}
var num = new Num(0);
num.increment().increment().decrement().increment();
console.log(num.getVal()); // 2
The non-chaining way would be:
var num = new Num(0);
num.increment();
num.increment();
num.decrement();
num.increment();
console.log(num.getVal()); // 2
A good reason to use chaining is when the method returns a new immutable object (e.g. string) but you don't care about the intermediary objects, you just want the final result:
var username = " Dave"; // user input with leading whitespace
var lowercase = username.trim().toLowerCase(); // "dave"
Not using chaining in this case wouldn't produce the desired result (no whitespace):
var username = " Dave"; // user input with leading whitespace
username.trim();
var lowercase = username.toLowerCase(); // " dave"
You could still avoid chaining though if you reassigned the return value:
var username = " Dave"; // user input with leading whitespace
var lowercase = username.trim();
lowercase = lowercase.toLowerCase(); // "dave"
And just for completeness, if you wanted to make the above Num
example immutable:
Num.prototype.increment = function () {
return new Num(this.val + 1);
}
Upvotes: 3