Nhảy tới nội dung

Proxy pattern trong Javascript là gì?

· Một phút để đọc

Hẳn là bạn đã dùng Javascript một thời gian dài, nhưng đã bao giờ bạn dùng đến Proxy trong Javascript hay chưa? Nếu chưa thì bài viết này là dành cho bạn.

Proxy là gì?

Proxy để dễ hiểu thì mình sẽ lấy ví dụ thế này: Tèo với Tí quánh lộn, Tí quánh không lại Tèo thế là Tí nhanh trí chơi chiêu méc với mẹ Tèo rằng Tèo quánh Tí sml. Thế rồi mẹ Tèo xách đầu Tèo về quánh Tèo sml, quánh Tèo xong mẹ Tèo dẫn Tèo qua nhà Tí xin lỗi Tí, (Tí mừng trong bụng cười hí hí). Thế là Tí đã "proxy" đánh Tèo nhờ mẹ Tèo. Đấy là chính là proxy, thay vì tác động trực tiếp tới Tèo, Tí đã thông qua trung gian là mẹ Tèo.

Trong Javascript cơ chế tương tự, thay vì tương tác trực tiếp với object chúng ta sẽ tương tác thông qua Proxy object.

Dùng proxy để làm gì?

Vậy câu hỏi đặt ra là cần proxy để làm gì? tại sao không tương tác trực tiếp luôn mà phải gián tiếp dùng proxy. Để trả lời cho câu hỏi trên mình sẽ đặt một câu hỏi ngược lại cho bạn. Đó là: Làm sao để mình thay đổi xong giá trị của một object trong Javascript thì mình biết nó đã thay đổi và làm một hành động gì đó khi nó thay đổi?

Bạn cứ từ từ đọc qua cách khai báo proxy đã câu trả lời nằm bên dưới.

Tạo proxy như thế nào?

Đầu tiên mình sẽ có một object như thế này:

const person = {
name: "John Doe",
age: 42,
nationality: "American"
};

Để tạo proxy cho object person thì cú pháp như sau:

const person = {
name: "John Doe",
age: 42,
nationality: "American"
};

const personProxy = new Proxy(person, {});

Rất đơn giản, chúng ta tạo một instance mới của class Proxy trong đó argument thứ nhất là target object, argument thứ 2 là một object chứa các handler. Có nhiều kiểu handler nhưng có 2 cái quan trọng là getset. Đặc biệt là set. Và đây là phần quan trọng và hữu dụng của proxy. Dùng proxy mà không có handler thì coi như vứt.

const personProxy = new Proxy(person, {
get: (obj, prop) => {
console.log(`The value of ${prop} is ${obj[prop]}`);
},
set: (obj, prop, value) => {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
obj[prop] = value;
}
});
  • get sẽ invoked khi giá trị của một thuộc tính được truy cập.
  • set sẽ invoked khi giá trị của một thuộc tính bị thay đổi giá trị.
const person = {
name: "John Doe",
age: 42,
nationality: "American"
};

const personProxy = new Proxy(person, {
get: (obj, prop) => {
console.log(`The value of ${prop} is ${obj[prop]}`);
},
set: (obj, prop, value) => {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
obj[prop] = value;
return true;
}
});

console.log(personProxy.name);
personProxy.age = 43;

Như vậy khi console.log(personProxy.name) chúng ta đang access giá trị thuộc tính của personProxy và thế là handler get sẽ chạy đoạn console.log(The value of ${prop} is ${obj[prop]});

Tương tự đối với set, khi ta gán personProxy.age = 13 thì handler set sẽ chạy.

Quay lại câu hỏi lúc nãy là: "Làm sao để mình thay đổi xong giá trị của một object trong Javascript thì mình biết nó đã thay đổi và làm một hành động gì đó khi nó thay đổi? ". Rất nhanh thôi câu trả lời là chúng ta sẽ dùng "set handler". Và từ đó mình có thể chèn bất kì behavior nào chúng ta ví dụ như validation, change detection, re-rendering... bất cứ cái gì cũng được. Đặc biệt hữu dụng cho Reactive Programming.

Mách nhỏ với bạn một package ứng dụng Proxy khá nổi tiếng của VueJS cho reactive programming là @vue/reactivity đấy. Không tin bạn mở code ra mà xem.

Tóm lại Proxy là công cụ built-in mạnh mẽ của Javascript để bạn control một object trong Javascript, bạn hoàn toàn có thể sử dụng nó để viết những code vượt ra khỏi các framework như React, Angular, Vue để có thể tái sử dụng được. Vanilla Javascript muôn năm!

Nếu bạn thấy bài viết hữu ích thì đừng ngần ngại mua giúp mình ly cà phê sữa đá nhé. Thanks.

Bài viết nguồn: https://www.patterns.dev/posts/proxy-pattern/

Official về proxy: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

img alt