Trong JavaScript, MapWeakMap đều là các cấu trúc dữ liệu được sử dụng để lưu trữ các cặp khóa-giá trị, nhưng chúng có những đặc điểm và cách hoạt động khác nhau. Dưới đây là sự khác biệt chính giữa chúng:

1. Đặc điểm và cấu trúc

  • Map:
    • Map là một cấu trúc dữ liệu lưu trữ các cặp khóa-giá trị, trong đó khóa có thể là bất kỳ kiểu dữ liệu nào (bao gồm cả đối tượng).
    • Các cặp khóa-giá trị trong Map sẽ giữ được tham chiếu đến cả khóa và giá trị, cho phép bạn truy cập và sửa đổi chúng bất kỳ lúc nào.
    • Map có tính thứ tự, tức là các phần tử sẽ được lưu trữ theo thứ tự mà chúng được thêm vào.
  • WeakMap:
    • WeakMap cũng là một cấu trúc dữ liệu lưu trữ các cặp khóa-giá trị, nhưng khóa phải là đối tượng (không phải kiểu dữ liệu nguyên thủy như số, chuỗi, boolean, v.v.).
    • WeakMap giữ tham chiếu yếu đến các khóa. Điều này có nghĩa là nếu không có tham chiếu nào khác đến một đối tượng được sử dụng làm khóa, thì đối tượng đó có thể bị garbage collection (thu gom rác) và xóa khỏi bộ nhớ.
    • WeakMap không giữ tham chiếu mạnh đến các khóa, do đó, không thể lặp qua các phần tử trong WeakMap.

2. Khả năng thu gom rác

  • Map:
    • Các khóa và giá trị trong Map được giữ lại cho đến khi Map bị xóa hoặc các giá trị được xóa một cách thủ công. Điều này có thể dẫn đến việc tiêu tốn bộ nhớ nếu không được quản lý đúng cách.
  • WeakMap:
    • Với WeakMap, khi không còn tham chiếu nào đến một khóa, nó có thể bị thu gom rác. Điều này giúp giải phóng bộ nhớ và ngăn chặn rò rỉ bộ nhớ trong ứng dụng.

3. Phương thức và Tính năng

  • Map:
    • Các phương thức của Map bao gồm: set(key, value), get(key), has(key), delete(key), và clear(). Bạn có thể sử dụng các phương thức này để quản lý các cặp khóa-giá trị.
    • Có thể lặp qua các phần tử trong Map bằng cách sử dụng các phương thức như forEach(), hoặc các iterator như keys(), values(), và entries().
  • WeakMap:
    • Các phương thức của WeakMap bao gồm: set(key, value), get(key), has(key), và delete(key). Tuy nhiên, không có phương thức nào để lặp qua các phần tử, vì các khóa có thể bị xóa bất cứ lúc nào.
    • Do đó, WeakMap không cung cấp các phương thức để lấy danh sách các khóa hoặc giá trị.

4. Sử dụng

  • Map:
    • Sử dụng Map khi bạn cần lưu trữ các cặp khóa-giá trị mà bạn muốn giữ lại cho đến khi nào bạn quyết định xóa chúng. Nó là lựa chọn tốt cho các ứng dụng cần lưu trữ dữ liệu với khả năng truy cập và sửa đổi dễ dàng.
  • WeakMap:
    • Sử dụng WeakMap khi bạn cần lưu trữ các tham chiếu đến các đối tượng mà bạn không muốn giữ lại mạnh mẽ. WeakMap là lựa chọn tốt cho các trường hợp như caching, nơi bạn muốn tự động giải phóng bộ nhớ khi không còn tham chiếu nào đến đối tượng.

Ví dụ minh họa

// Ví dụ với Map
const map = new Map();
const obj1 = { id: 1 };
const obj2 = { id: 2 };

map.set(obj1, 'Object 1');
map.set(obj2, 'Object 2');

console.log(map.get(obj1)); // In ra 'Object 1'

// Ví dụ với WeakMap
const weakMap = new WeakMap();
const obj3 = { id: 3 };
const obj4 = { id: 4 };

weakMap.set(obj3, 'Object 3');
weakMap.set(obj4, 'Object 4');

console.log(weakMap.get(obj3)); // In ra 'Object 3'

// Nếu không còn tham chiếu đến obj3, nó sẽ bị thu gom rác

Kết luận

MapWeakMap đều có những ứng dụng và tính năng riêng biệt trong JavaScript. Việc chọn cấu trúc nào phụ thuộc vào nhu cầu cụ thể của ứng dụng của bạn, đặc biệt là trong việc quản lý bộ nhớ và khả năng truy cập dữ liệu. Nếu bạn cần giữ lại các cặp khóa-giá trị và lặp qua chúng, hãy sử dụng Map. Ngược lại, nếu bạn cần các khóa là đối tượng và muốn tránh rò rỉ bộ nhớ, WeakMap là lựa chọn hợp lý.