Cách thức hoạt động của proxy object trong JavaScript

Proxy object cho bạn một cách để ghi đè hành vi của đối tượng đã được xác định. Dưới đây là những điều bạn cần biết về cách thức hoạt động của proxy object trong JavaScript.

Proxy Object

Một proxy object trong JavaScript cho phép bạn chặn và tùy chỉnh hành vi của đối tượng khác mà không cần phải chỉnh sửa bản gốc.

Dùng proxy object, bạn có thể xác thực dữ liệu, cung cấp thêm tính năng và kiểm soát truy cập tới các thuộc tính và hàm.

Tạo proxy object trong JavaScript

Trong JavaScript, bạn có thể tạo các proxy object bằng Proxy constructor. Công cụ này xem xét hai thành phần: một đối tượng mục tiêu để “gói” proxy xung quanh và một đối tượng handler mà thuộc tính của nó quyết định hành vi của proxy khi bạn thực hiện các thao tác. Từ đó, bạn tạo được đối tượng có thể dùng ở object mục tiêu.

Đối tượng được tạo này có thể xác định lại các hoạt động cốt lõi như nhận, thiết lập và xác định các thuộc tính. Bạn cũng có thể dùng những proxy object đó để lưu các truy cập thuộc tính, xác thực, định dạng hoặc cải thiện điều kiện input.

Ví dụ:

  foo: "bar"
}

const handler = {
  get: function(target, property) {
    return target[property];
  },
  set: function(target, property, value) {
    target[property] = value;
  }
};

const proxy = new Proxy(originalObject, handler)

Code này tạo một object mục tiêu, originalObject với một thuộc tính đơn lẻ, foo, và một object xử lý, handler. Đối tượng này chứa hai thuộc tính, get set. Chúng còn được gọi là bẫy.

Proxy object là một hàm được gọi bất cứ khi nào bạn triển khai một tác vụ cụ thể trên một proxy object. Các bẫy cho phép bạn chặn và tùy biến hành vi của proxy object. Truy cập một thuộc tính từ proxy object gọi bẫy get, đồng thời chỉnh sửa hoặc thao tác một thuộc tính từ đối tượng proxy gọi trap set.

Cuối cùng, code này tao một proxy object với hàm tạo Proxy. Nó lần lượt chuyển originalOjecthandler dưới dạng đối tượng và trình xử lý mục tiêu.

Dùng các đối tượng proxy

Bạn có một số cách dùng proxy object trong JavaScript, một vài trong số chúng như sau:

Thêm chức năng vào một đối tượng

Bạn có thể dùng proxy object để đóng gói một đối tượng hiện tại và thêm chức năng mới, chẳng hạn như ghi nhật ký hay xử lý lỗi mà không cần chỉnh sửa đối tượng ban đầu.

Để thêm chức năng mới, bạn cần dùng trình tạo Proxy và xác định một hoặc nhiều bẫy hơn cho các tác vụ muốn chặn.

Ví dụ:

const userObject = {
  firstName: "Kennedy",
  lastName: "Martins",
  age: 20,
};

const handler = {
  get: function (target, property) {
    console.log(`Getting property "${property}"`);
    return target[property];
  },
  set: function (target, property, value) {
    console.log(`Setting property "${property}" to value "${value}"`);
    target[property] = value;
  },
};

const proxy = new Proxy(userObject, handler);

console.log(proxy.firstName); // Getting property "firstName" Kennedy
console.log(proxy.lastName); // Getting property "lastName" Martins
proxy.age = 23; // Setting property "age" to value "23"

Khối code này thêm chức năng qua proxy trap, get set. Giờ khi bạn thử truy cập hoặc chỉnh sửa một thuộc tính của userObject, đầu tiên, proxy object này sẽ lưu hoạt động của bạn vào bảng điều khiển trước khi truy cập hay chỉnh sửa thuộc tính.

Xác thực dữ liệu trước khi thiết lập nó trên một đối tượng

Bạn có thể dùng các đối tượng proxy để xác thực dữ liệu và đảm bảo nó đáp ứng tiêu chí cụ thể trước khi thiết lập nó trên một đối tượng. Bạn có thể làm như thế bằng cách xác định logic xác thực trong một trap sethandler object.

Ví dụ:

const userObject = {
  firstName: "Kennedy",
  lastName: "Martins",
  age: 20,
};

const handler = {
  get: function (target, property) {
    console.log(`Getting property "${property}"`);
    return target[property];
  },
  set: function (target, property, value) {
    if (
      property === "age" &&
      typeof value == "number" &&
      value > 0 &&
      value < 120
    ) {
      console.log(`Setting property "${property}" to value "${value}"`);
      target[property] = value;
    } else {
      throw new Error("Invalid parameter. Please review and correct.");
    }
  },
};

const proxy = new Proxy(userObject, handler);
proxy.age = 21;

Khối code này bổ sung các quy tắc xác thực vào trap set. Bạn có thể gắn giá trị bất kỳ vào thuộc tính age trên phiên bản userObject. Thế nhưng, với những quy tắc hợp lệ đã bổ sung, bạn chỉ có thể gắn một giá trị mới vào thuộc tính age nếu nó là một số, lớn hơn 0 và nhỏ hơn 120. Bất kỳ giá trị bạn muốn thiết lập trên thuộc tính age không đáp ứng điều kiện, tiêu chí cần thiết sẽ kích hoạt một lỗi và phát thông báo lỗi.

Kiểm soát truy cập tới các thuộc tính đối tượng

Bạn có thể dùng các proxy object để ẩn những thuộc tính cụ thể của một đối tượng. Làm việc này bằng cách xác định logic hạn chế trong trap get cho thuộc tính bạn muốn kiểm soát truy cập.

Ví dụ:

const userObject = {
  firstName: "Kennedy",
  lastName: "Martins",
  age: 20,
  phone: 1234567890,
  email: "foo@bar.com",
};

const handler = {
  get: function (target, property) {
    if (property === "phone" || property === "email") {
      throw new Error("Access to info denied");
    } else {
      console.log(`Getting property "${property}"`);
      return target[property];
    }
  },
  set: function (target, property, value) {
    console.log(`Setting property "${property}" to value "${value}"`);
    target[property] = value;
  },
};

const proxy = new Proxy(userObject, handler);

console.log(proxy.firstName); // Getting property "firstName" Kennedy
console.log(proxy.email); // Throws error

Khối code ở trên bổ sung các hạn chế cụ thể cho trap get. Ban đầu, bạn có thể truy cập tất cả thuộc tính sẵn có trên userObject. Những nguyên tắc bổ sung chặn truy cập tới thông tin nhạy cảm như email hoặc điện thoại của người dùng. Thử truy cập thuộc tính khác sẽ phát sinh lỗi.

Proxy trap khác

Trap get set là phổ biến và hữu ích nhất nhưng có 11 proxy trap JavaScript khác. Chúng là:

  • apply: Trap apply chạy khi bạn gọi một hàm trên đối tượng proxy.
    construct: Trap construct chạy khi bạn sử dụng toán tử mới để tạo một đối tượng từ đối tượng proxy.
  • deleteProperty: Bẫy deleteProperty chạy khi bạn sử dụng toán tử xóa để xóa một thuộc tính khỏi đối tượng proxy.
  • has - Bẫy has chạy khi bạn sử dụng toán tử in để kiểm tra xem một thuộc tính có tồn tại trên đối tượng proxy hay không.
  • ownKeys - Bẫy ownKeys chạy khi bạn gọi hàm Object.getOwnPropertyNames hoặc Object.getOwnPropertySymbols trên đối tượng proxy.
  • getOwnPropertyDescriptor - Bẫy getOwnPropertyDescriptor chạy khi bạn gọi hàm Object.getOwnPropertyDescriptor trên đối tượng proxy.
  • defineProperty - Bẫy defineProperty chạy khi bạn gọi hàm Object.defineProperty trên đối tượng proxy.
  • preventExtensions - Bẫy preventExtensions chạy khi bạn gọi hàm Object.preventExtensions trên đối tượng proxy.
  • isExtensible - Bẫy isExtensible chạy khi bạn gọi hàm Object.isExtensible trên đối tượng proxy.
  • getPrototypeOf - Bẫy getPrototypeOf chạy khi bạn gọi hàm Object.getPrototypeOf trên đối tượng proxy.
  • setPrototypeOf - Bẫy setPrototypeOf chạy khi bạn gọi hàm Object.setPrototypeOf trên đối tượng proxy.

Giống như trap setget, bạn có thể dùng những trap đó để thêm layer chức năng mới, xác thực và kiểm soát đối tượng mà không chỉnh sửa bản gốc.

Proxy object có thể là công cụ mạnh mẽ cho bạn thêm chức năng tùy biến hoặc xác thực đối tượng. Tuy nhiên, chúng cũng khá khó debug và không hề dễ sử dụng với người mới bắt đầu.

Trên đây là mọi điều bạn cần biết về proxy object trong JavaScript. Hi vọng bài viết hữu ích với các bạn.

Thứ Hai, 09/01/2023 16:52
31 👨 222
0 Bình luận
Sắp xếp theo