Method Chaining trong JavaScript

Post Reply
User avatar
stararound
Posts: 27
Joined: Wed Apr 17, 2019 1:29 pm

Method Chaining trong JavaScript

Post by stararound »

Method Chaining là một pattern phổ biến trong JavaScript khá quen thuộc với Javascript Programer. Method Chainning là một kỹ thuật được sử dụng để viết code một cách ngắn gọn và đơn giản hơn trong việc gọi các hàm liên tiếp trên cùng một đối tượng, nó sẽ gọi một chuỗi các hàm trong một câu lệnh duy nhất.

Đây là một ví dụ về cách bạn sử dụng method chaining trong jQuery.

Code: Select all

// Không sử dung METHOD CHAINING
 
var $div = $('#my-div');
 
$div.css('background', 'blue');
$div.height(100);
$div.fadeIn(200);
 
// Sử dụng METHOD CHAINING
 
$('#my-div').css('background', 'blue').height(100).fadeIn(200);
// hoặc đẹp hơn sẽ là:
$('#my-div')
  .css('background', 'blue')
  .height(100)
  .fadeIn(200);
Minh họa cách thông thường, không sử dụng method chaining, ta sẽ định nghĩa một lớp Kitten với một vài phương thức để gọi như sau:

MINH HỌA SỐ 1

Code: Select all

// define the class
var Kitten = function() {
  this.name = 'Garfield';
  this.color = 'brown';
  this.gender = 'male';
};
 
Kitten.prototype.setName = function(name) {
  this.name = name;
};
 
Kitten.prototype.setColor = function(color) {
  this.color = color;
};
 
Kitten.prototype.setGender = function(gender) {
  this.gender = gender;
};
 
Kitten.prototype.save = function() {
  console.log(
    'saving ' + this.name + ', the ' +
    this.color + ' ' + this.gender + ' kitten...'
  );
 
  // save to database here...
};

// Sử dụng đúng:
var bob = new Kitten();
 
bob.setName('Bob');
bob.setColor('black');
bob.setGender('male');
 
bob.save();
 
// OUTPUT:
// > saving Bob, the black male kitten...

// Sử dụng sai:
var bob = new Kitten();
 
bob.setName('Bob').setColor('black');

// ERROR:
// > Uncaught TypeError: Cannot call method 'setColor' of undefined

Method Chainning sẽ là hoàn hảo cho việc giải quết vấn đề lặp lại ở cách code trên, ta viết lại lớp Kitten như sau:

MINH HỌA SỐ 2

Code: Select all

// define the class
var Kitten = function() {
  this.name = 'Garfield';
  this.color = 'brown';
  this.gender = 'male';
};
 
// Khác biệt so với code bên trên ở đây: lệnh return this;
Kitten.prototype.setName = function(name) {
  this.name = name;
  return this; // Khác biệt ở đây
};
 
Kitten.prototype.setColor = function(color) {
  this.color = color;
  return this; // Khác biệt ở đây
};
 
Kitten.prototype.setGender = function(gender) {
  this.gender = gender;
  return this; // Khác biệt ở đây
};
 
Kitten.prototype.save = function() {
  console.log(
    'saving ' + this.name + ', the ' +
    this.color + ' ' + this.gender + ' kitten...'
  );
 
  // save to database here...
 
  return this; // Khác biệt ở đây
};

// Sử dụng: 
// WITHOUT CHAINING
 
var bob = new Kitten();
 
bob.setName('Bob');
bob.setColor('black');
bob.setGender('male');
 
bob.save();
 
// OUTPUT:
// > saving Bob, the black male kitten...
 
// WITH CHAINING
 
new Kitten()
  .setName('Bob')
  .setColor('black')
  .setGender('male')
  .save();
 
// OUTPUT:
// > saving Bob, the black male kitten...
Bằng cách sử dụng phương thức Method Chainning, ta sẽ code gọn gàng, dễ hiểu và trông pro hơn rất nhiều.

BONUS:

Để xử lý bổ sung tự động return this; cho MINH HỌA SỐ 1 ta có thể sử dụng cách sau:

Code: Select all

// Sử dụng hàm chainify
function chainify(obj) {
    Object.keys(obj).forEach(function(key){
        var member = obj[key];
        if(typeof member === "function" && !/\breturn\b/.test(member)){
            obj[key] = function() {
                member.apply(this, arguments);
                return this;
            }
        }
    });
}

// Thực hiện lệnh này để bổ sung tự động return this;
chainify(Kitten.prototype);

// Vậy là ok
var bob = new Kitten()
  .setName('Bob')
  .setColor('black')
  .setGender('male')
  .save();

Post Reply