DEV Community

Cover image for JavaScript Chaining
sundarbadagala
sundarbadagala

Posted on • Edited on

JavaScript Chaining

INTRO 🔊

Chaining is the concept one function returns a current(this) object and another function will use values in that current(this) object. It's the same as PIPELINE explained in my previous post. But the difference is in chaining we have pre-defined methods not like a pipeline. Javascript chaining is a very familiar concept. If you know array methods then you automatically know javascript chaining.

DEFINITION 🔊

Method Chaining is a programming strategy that simplifies and embellishes your code. It is a mechanism for calling a method on another method of the same object.

USAGE 🔊

For example, if we want to use one method/function modified value in another method/function every time we have to call that method/function and have to pass the returned value from the previous function to the next method/function. It leads to more code, lacks the best practice and affects the performance.

EXAMPLE 🔊

For example let's take four functions named add, subtract, divide, multiple. We have to use the value returned from the function add into subtract, later we have to use the returned value from subtract into divide, and in that same way, we have to use the returned value from divide into multiple and finally should be return the value.

WITHOUT CHAIN 🔕

const add=(i,num )=>{
   return i + num //16
}

const subtract=(i, num)=>{
   return i - num //12
}

const divide=(i, num)=>{
   return i / num //4
}

const multiple=(i, num)=>{
   return i * num //8
}

let x = 10
const a = add(x, 6)
const b = subtract(a, 4)
const c = divide(b, 3)
const res = multiple(c, 2)

console.log(res)
Enter fullscreen mode Exit fullscreen mode

If you observe the above code we wrote all 4 methods individually and defined them one by one. It takes up more space and code is also not much readable.

const add=(num, a)=> {
   return num + a
}
const subtract=(num, a)=>{
   return num - a
}
const divide=(num, a)=>{
    return num / a
}
const multiple=(num, a)=>{
   return num * a
}

const res = multiple(divide(subtract(add(10, 6), 4), 3), 2)

console.log(res)  //8
Enter fullscreen mode Exit fullscreen mode

By using the Higher Order Function method, the code is not readable and it's taking right to left format (usually the code should be in left to right format) which is a little bit confusing.

const add=(callback, num)=> {
    return callback(num + 6)
}
const subtract=(callback, a)=>{
    return callback(a - 4)
}
const divide=(callback, a)=>{
    return callback(a / 3)
}
const multiple=(callback, a)=>{
    return callback(a * 2)
}

const res = add((a)=>{
    return subtract((b)=>{
      return multiple((c)=>{
          return divide((d)=>{
             return d
          }, c)
      }, b)
    }, a)
}, 10)

console.log(res)
Enter fullscreen mode Exit fullscreen mode

With the callback method, It creates callback hell, not readable and not very efficient.

WITH CHAIN 🔔

function main(num) {
  let i = num;
  return {
    add: function (num) {
      i += num;
      return this;
    },
    subtract: function (num) {
      i -= num;
      return this;
    },
    divide: function (num) {
      i /= num;
      return this;
    },
    multiple: function (num) {
      i *= num;
      return this;
    },
    print() {
      return i;
    },
  };
}

const x = main(10)
const res = x.add(6).subtract(4).divide(3).multiple(2).print();

cosole.log(res)
Enter fullscreen mode Exit fullscreen mode

The above code is very readable and we can consider it as the best practice method compared to the previous one.

DIFFERENT WAYS TO ACHIEVE CHAINING IN JAVASCRIPT 🔊

FACTORY FUNCTIONS 📕

function main(num) {
  let i = num;
  return {
    add: function (num) {
      i += num;
      return this;
    },
    subtract: function (num) {
      i -= num;
      return this;
    },
    divide: function (num) {
      i /= num;
      return this;
    },
    multiple: function (num) {
      i *= num;
      return this;
    },
    print() {
      return i;
    },
  };
}

const x1 = main(10);
const x2 = main(10);

const value = x1.add(6).subtract(4).multiple(3).divide(2).print();
const value2 = x2.multiple(3).add(6).subtract(4).divide(2).print();
const value3 = x2.multiple(5).divide(4).print()

console.log(value);     //18
console.log(value2);    //16
console.log(value3)     //20
Enter fullscreen mode Exit fullscreen mode

CONSTRUCTOR FUNCTIONS 📗

const main = function (init = 0) {
  this.i = init;
  this.add = function (i) {
    this.i += i;
    return this;
  };
 this.subtract = function (i) {
    this.i -= i;
    return this;
  };
  this.multiple = function (i) {
    this.i *= i;
    return this;
  };
 this.divide = function (i) {
    this.i /= i;
    return this;
  };
  this.print = function () {
    return this.i;
  };
};

const x1 = new main(10);
const x2 = new main(10);

const value = x1.add(6).subtract(4).multiple(3).divide(2).print();
const value2 = x2.multiple(3).add(6).subtract(4).divide(2).print();
const value3 = x2.multiple(5).divide(4).print()

console.log(value);     //18
console.log(value2);    //16
console.log(value3)     //20
Enter fullscreen mode Exit fullscreen mode

CLASS METHODS 📘

class Main {
  constructor(data) {
    this.data = data;
  }
  add(num) {
    this.data += num;
    return this;
  }
  subtract(num) {
    this.data -= num;
    return this;
  }
  divide(num){
      this.data /= num;
      return this;
  }
  multiple(num) {
    this.data *= num;
    return this;
  }
  print() {
    return this.data;
  }
}

const x1 = new Main(10);
const x2 = new Main(10)

const value = x1.add(6).subtract(4).multiple(3).divide(2).print();
const value2 = x2.multiple(3).add(6).subtract(4).divide(2).print();
const value3 = x2.multiple(5).divide(4).print()

console.log(value);     //18
console.log(value2);    //16
console.log(value3)     //20
Enter fullscreen mode Exit fullscreen mode

OBJECT METHODS 📙

const main = {
  data: {
    i: 0,
  },
  initiate: function (num = 0) {
    this.data.i = num;
    return this;
  },
  add: function (num) {
    this.data.i += num;
    return this;
  },
  subtract: function (num) {
    this.data.i -= num;
    return this;
  },
  multiple: function (num) {
    this.data.i *= num;
    return this;
  },
  divide: function (num) {
    this.data.i /= num;
    return this;
  },
  print: function () {
    return this.data.i;
  },
};

const value = main.initiate(10).add(6).subtract(4).divide(3).multiple(2).print();
const value2 = main.initiate(10).multiple(3).add(6).subtract(4).divide(2).print();

console.log(value);     //8
console.log(value2)     //16
Enter fullscreen mode Exit fullscreen mode

SIMILAR TO ARRAY METHODS 🔊

If you observe array methods like map, filter, reduce etc... they are also follows the same code practice

For Example :-

Array.map().filter().reducer()
Enter fullscreen mode Exit fullscreen mode

CONCLUSION 🔊

Chaining is the one of the best practice method for create multiple methods depends on one on another. same like array methods. It looks clean and readable. So from now onwards if we want to write multiple dependent methods, follow the chaining method 😎

Peace 😊

Top comments (0)