JavaScript - Đối tượng WeakSet

Xin chào, những người học lập trình! Hôm nay, chúng ta sẽ khám phá một tính năng thú vị nhưng thường bị bỏ qua của JavaScript: đối tượng WeakSet. Đừng lo lắng nếu bạn là người mới bắt đầu lập trình; tôi sẽ hướng dẫn bạn qua khái niệm này từng bước một, giống như tôi đã làm cho hàng trăm học viên trong những năm dạy học của mình. Vậy, hãy lấy饮料 yêu thích của bạn, ngồi thoải mái, và cùng nhau khám phá nhé!

JavaScript - WeakSet

WeakSet là gì?

Trước khi chúng ta đi vào chi tiết, hãy hiểu xem WeakSet là gì. Hãy tưởng tượng bạn có một hộp đặc biệt nơi bạn chỉ có thể đặt các món đồ chơi duy nhất, nhưng những món đồ chơi này sẽ biến mất một cách kỳ diệu khi không có ai chơi với chúng nữa. Đó giống như một WeakSet trong JavaScript!

WeakSet là một tập hợp các đối tượng, nhưng với một số đặc điểm đặc biệt:

  1. Nó chỉ có thể lưu trữ các đối tượng, không phải giá trị nguyên thủy.
  2. Các đối tượng trong một WeakSet được tham chiếu yếu, có nghĩa là chúng có thể bị thu hồi rác nếu không có tham chiếu khác đến chúng.
  3. WeakSets không thể đếm, vì vậy bạn không thể vòng lặp qua chúng.

Bây giờ, hãy cùng xem cách tạo và sử dụng một WeakSet.

Cú pháp

Tạo một WeakSet rất dễ dàng. Dưới đây là cách bạn làm:

let myWeakSet = new WeakSet();

Đó là tất cả! Bạn vừa tạo một WeakSet trống. Bây giờ, hãy thêm một số đối tượng vào nó.

let obj1 = { name: "Alice" };
let obj2 = { name: "Bob" };

myWeakSet.add(obj1);
myWeakSet.add(obj2);

console.log(myWeakSet.has(obj1)); // Output: true
console.log(myWeakSet.has(obj2)); // Output: true

Trong ví dụ này, chúng ta đã tạo hai đối tượng và thêm chúng vào WeakSet của mình. Phương thức has() kiểm tra xem một đối tượng có trong WeakSet hay không.

Thuộc tính của WeakSet

Bây giờ, bạn có thể tự hỏi, "WeakSet có những thuộc tính nào?" Được rồi, đây là một sự thật thú vị: WeakSets không có thuộc tính! Đúng vậy, không có gì, không có gì, không có gì! Điều này vì WeakSets được thiết kế để nhẹ và không theo dõi kích thước hoặc nội dung của chúng.

Phương thức của WeakSet

Trong khi WeakSets không có thuộc tính, chúng có một số phương thức hữu ích. Hãy cùng xem chúng trong bảng:

Phương thức Mô tả
add(value) Thêm một đối tượng mới vào WeakSet
delete(value) Xóa một đối tượng cụ thể khỏi WeakSet
has(value) Kiểm tra xem một đối tượng cụ thể có存在于 WeakSet hay không

Hãy xem các phương thức này trong hành động:

let weakSet = new WeakSet();
let obj = { id: 1 };

// Thêm một đối tượng
weakSet.add(obj);
console.log(weakSet.has(obj)); // Output: true

// Thử xóa đối tượng
weakSet.delete(obj);
console.log(weakSet.has(obj)); // Output: false

// Thử thêm một giá trị không phải đối tượng (sẽ ném ra lỗi)
try {
weakSet.add(1);
} catch(error) {
console.log("Error:", error.message);
}
// Output: Error: Invalid value used in weak set

Trong ví dụ này, chúng ta đã sử dụng tất cả ba phương thức của một WeakSet. Lưu ý rằng việc cố gắng thêm một giá trị không phải đối tượng (như số 1) sẽ gây ra lỗi. Nhớ lại, WeakSets chỉ dành cho các đối tượng!

Ví dụ

Bây giờ chúng ta đã bao gồm các nguyên tắc cơ bản, hãy xem một số ví dụ thực tế khi bạn có thể sử dụng một WeakSet.

Ví dụ 1: Theo dõi các trang đã truy cập

Hãy tưởng tượng bạn đang xây dựng một trang web và muốn theo dõi các trang mà người dùng đã truy cập, nhưng chỉ khi họ đang tích cực duyệt网页:

let visitedPages = new WeakSet();

class Page {
constructor(url) {
this.url = url;
}

visit() {
visitedPages.add(this);
console.log(`Visited: ${this.url}`);
}

hasVisited() {
return visitedPages.has(this);
}
}

let homePage = new Page("https://example.com");
let aboutPage = new Page("https://example.com/about");

homePage.visit(); // Output: Visited: https://example.com
console.log(homePage.hasVisited()); // Output: true
console.log(aboutPage.hasVisited()); // Output: false

Trong ví dụ này, chúng ta sử dụng một WeakSet để theo dõi các đối tượng Page đã truy cập. WeakSet cho phép các đối tượng Page bị thu hồi rác khi chúng không còn được cần thiết, điều này rất tốt cho quản lý bộ nhớ!

Ví dụ 2: Ngăn chặn xử lý trùng lặp

Hãy giả sử bạn đang viết một chương trình xử lý dữ liệu người dùng, nhưng bạn muốn đảm bảo rằng mỗi người dùng chỉ được xử lý một lần:

let processedUsers = new WeakSet();

function processUser(user) {
if (processedUsers.has(user)) {
console.log(`User ${user.name} has already been processed.`);
return;
}

// Xử lý người dùng...
console.log(`Processing user: ${user.name}`);
processedUsers.add(user);
}

let user1 = { name: "Alice" };
let user2 = { name: "Bob" };

processUser(user1); // Output: Processing user: Alice
processUser(user2); // Output: Processing user: Bob
processUser(user1); // Output: User Alice has already been processed.

Trong ví dụ này, chúng ta sử dụng một WeakSet để theo dõi những người dùng đã được xử lý. Điều này ngăn chặn việc xử lý trùng lặp và rất tiết kiệm bộ nhớ vì nếu một đối tượng người dùng không còn được tham chiếu ở nơi khác trong mã của bạn, nó có thể bị thu hồi rác cùng với mục nhập của nó trong WeakSet.

Kết luận

Và đó là tất cả, các bạn! Chúng ta đã khám phá thế giới bí ẩn của WeakSets trong JavaScript. Nhớ lại, WeakSets giống như người bạn cool, tối giản không muốn giữ gìn quá lâu. Chúng hoàn hảo khi bạn cần liên kết các đối tượng với một trạng thái hoặc hành vi cụ thể, nhưng bạn không muốn ngăn cản các đối tượng đó bị thu hồi rác.

WeakSets có thể không phải là thứ bạn sử dụng hàng ngày, nhưng việc hiểu chúng thêm một công cụ mạnh mẽ vào bộ công cụ JavaScript của bạn. Ai biết được? Một ngày nào đó, bạn có thể gặp phải tình huống mà một WeakSet chính là điều bạn cần để giải quyết một vấn đề khó khăn.

Tiếp tục lập trình, giữ vững sự tò mò, và nhớ rằng: trong thế giới lập trình, luôn có điều mới để học!

Credits: Image by storyset