Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WeakMap and WeakSet #193

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
Let's store read messages in `WeakSet`:
Hãy lưu trữ tin nhắn đã đọc trong `WeakSet`:

```js run
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
{text: "Xin chào", from: "John"},
{text: "Tiến triển thế nào rồi?", from: "John"},
{text: "Hẹn sớm gặp lại", from: "Alice"}
];

let readMessages = new WeakSet();

// two messages have been read
// hai tin nhắn đã được đọc
readMessages.add(messages[0]);
readMessages.add(messages[1]);
// readMessages has 2 elements

// ...let's read the first message again!
// ...hãy đọc lại tin nhắn đầu tiên!
readMessages.add(messages[0]);
// readMessages still has 2 unique elements
// readMessages vẫn có 2 yếu tố độc nhất

// answer: was the message[0] read?
// trả lời: messages[0] đã được đọc chưa?
alert("Read message 0: " + readMessages.has(messages[0])); // true

messages.shift();
// now readMessages has 1 element (technically memory may be cleaned later)
// bây giờ readMessages 1 phần tử (về mặt kỹ thuật, bộ nhớ có thể được xóa sau)
```

The `WeakSet` allows to store a set of messages and easily check for the existence of a message in it.
`WeakSet` cho phép lưu trữ một tập hợp các thông báo và dễ dàng kiểm tra sự tồn tại của một thông báo trong đó.

It cleans up itself automatically. The tradeoff is that we can't iterate over it, can't get "all read messages" from it directly. But we can do it by iterating over all messages and filtering those that are in the set.
Nó tự động dọn dẹp. Sự đánh đổi là chúng ta không thể lặp lại nó, không thể nhận trực tiếp "tất cả các tin nhắn đã đọc" từ nó. Nhưng chúng ta có thể làm điều đó bằng cách lặp lại tất cả các tin nhắn và lọc những tin nhắn có trong set.

Another, different solution could be to add a property like `message.isRead=true` to a message after it's read. As messages objects are managed by another code, that's generally discouraged, but we can use a symbolic property to avoid conflicts.
Một giải pháp khác, khác có thể là thêm thuộc tính như `message.isRead=true` vào tin nhắn sau khi tin nhắn được đọc. Vì các đối tượng thông báo được quản lý bởi một mã khác, điều đó thường không được khuyến khích, nhưng chúng ta có thể sử dụng một thuộc tính tượng trưng để tránh xung đột.

Like this:
Như thế này:
```js
// the symbolic property is only known to our code
// thuộc tính tượng trưng chỉ được biết đến với mã của chúng ta
let isRead = Symbol("isRead");
messages[0][isRead] = true;
```

Now third-party code probably won't see our extra property.
Bây giờ mã của bên thứ ba có thể sẽ không thấy thuộc tính bổ sung của chúng ta.

Although symbols allow to lower the probability of problems, using `WeakSet` is better from the architectural point of view.
Mặc dù các ký hiệu cho phép giảm xác suất xảy ra sự cố, nhưng sử dụng `WeakSet` sẽ tốt hơn từ quan điểm kiến trúc.
18 changes: 9 additions & 9 deletions 1-js/05-data-types/08-weakmap-weakset/01-recipients-read/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ importance: 5

---

# Store "unread" flags
# Lưu trữ cờ "chưa đọc"

There's an array of messages:
Có một array các tin nhắn:

```js
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
{text: "Xin chào", from: "John"},
{text: "Tiến triển thế nào rồi?", from: "John"},
{text: "Hẹn sớm gặp lại", from: "Alice"}
];
```

Your code can access it, but the messages are managed by someone else's code. New messages are added, old ones are removed regularly by that code, and you don't know the exact moments when it happens.
Mã của bạn có thể truy cập nó, nhưng các tin nhắn được quản lý bởi mã của người khác. Các tin nhắn mới được thêm vào, các tin nhắn cũ bị mã đó xóa thường xuyên và bạn không biết chính xác thời điểm nó xảy ra.

Now, which data structure could you use to store information about whether the message "has been read"? The structure must be well-suited to give the answer "was it read?" for the given message object.
Bây giờ, bạn có thể sử dụng cấu trúc dữ liệu nào để lưu trữ thông tin về việc thư "đã được đọc" chưa? Cấu trúc phải phù hợp để đưa ra câu trả lời "đã đọc chưa?" cho đối tượng thông báo đã cho.

P.S. When a message is removed from `messages`, it should disappear from your structure as well.
Tái bút: Khi một tin nhắn bị xóa khỏi `messages`, nó cũng sẽ biến mất khỏi cấu trúc của bạn.

P.P.S. We shouldn't modify message objects, add our properties to them. As they are managed by someone else's code, that may lead to bad consequences.
Tái bút nữa: Chúng ta không nên sửa đổi các đối tượng tin nhắn, hãy thêm các thuộc tính của chúng ta vào chúng. Vì chúng được quản lý bởi mã của người khác, điều đó có thể dẫn đến hậu quả xấu.
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

To store a date, we can use `WeakMap`:
Để lưu trữ một ngày, chúng ta có thể sử dụng `WeakMap`:

```js
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
{text: "Xin chào", from: "John"},
{text: "Tiến triển thế nào rồi?", from: "John"},
{text: "Hẹn sớm gặp lại", from: "Alice"}
];

let readMap = new WeakMap();

readMap.set(messages[0], new Date(2017, 1, 1));
// Date object we'll study later
// Đối tượng ngày chúng ta sẽ nghiên cứu sau
```
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ importance: 5

---

# Store read dates
# Lưu trữ ngày đọc

There's an array of messages as in the [previous task](info:task/recipients-read). The situation is similar.
Có một array tin nhắn như trong [bài tập trước đó](info:task/recipients-read). Tình hình cũng tương tự.

```js
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
{text: "Xin chào", from: "John"},
{text: "Tiến triển thế nào rồi?", from: "John"},
{text: "Hẹn sớm gặp lại", from: "Alice"}
];
```

The question now is: which data structure you'd suggest to store the information: "when the message was read?".
Câu hỏi bây giờ là: bạn muốn đề xuất cấu trúc dữ liệu nào để lưu trữ thông tin: "khi tin nhắn được đọc?".

In the previous task we only needed to store the "yes/no" fact. Now we need to store the date, and it should only remain in memory until the message is garbage collected.
Trong bài tập trước, chúng ta chỉ cần lưu trữ dữ kiện "có/không". Bây giờ chúng ta cần lưu trữ ngày tháng và nó chỉ nên lưu lại trong bộ nhớ cho đến khi thư được thu gom rác.

P.S. Dates can be stored as objects of built-in `Date` class, that we'll cover later.
Tái bút: Ngày tháng có thể được lưu trữ dưới dạng đối tượng của class `Date` tích hợp sẵn, mà chúng ta sẽ đề cập sau.
Loading