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 #196

Merged
merged 2 commits into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
Let's store read messages in `WeakSet`:
Lass uns gelesene Nachrichten in `WeakSet` speichern:

```js run
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
{text: "Hallo", from: "John"},
{text: "Wie läuft's?", from: "John"},
{text: "Bis bald", from: "Alice"}
];

let readMessages = new WeakSet();

// two messages have been read
// Zwei Nachrichten wurden gelesen
readMessages.add(messages[0]);
readMessages.add(messages[1]);
// readMessages has 2 elements
// readMessages hat 2 Elemente

// ...let's read the first message again!
// ...lass uns die erste Nachricht nochmal lesen!
readMessages.add(messages[0]);
// readMessages still has 2 unique elements
// readMessages hat immer noch 2 einzigartige Elemente

// answer: was the message[0] read?
alert("Read message 0: " + readMessages.has(messages[0])); // true
// Antwort: Wurde die Nachricht[0] gelesen?
alert("Gelesene Nachricht 0: " + readMessages.has(messages[0])); // true

messages.shift();
// now readMessages has 1 element (technically memory may be cleaned later)
// jetzt hat readMessages 1 Element (technisch gesehen, könnte der Speicher später bereinigt werden)
```

The `WeakSet` allows to store a set of messages and easily check for the existence of a message in it.
Das `WeakSet` ermöglicht es, eine Menge von Nachrichten zu speichern und einfach zu überprüfen, ob eine Nachricht darin existiert.

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.
Es bereinigt sich automatisch. Der Kompromiss ist, dass wir nicht darüber iterieren können, d.h. wir können nicht "alle gelesenen Nachrichten" direkt erhalten. Aber wir können dies erreichen, indem wir über alle Nachrichten iterieren und diejenigen aussortieren, die nicht im Set sind.

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.
Eine andere, unterschiedliche Lösung könnte sein, einer Nachricht eine Eigenschaft wie `message.isRead=true` hinzuzufügen, nachdem sie gelesen wurde. Da Nachrichtenobjekte von anderem Code verwaltet werden, ist das allgemein nicht empfohlen, aber wir können eine symbolische Eigenschaft verwenden, um Konflikte zu vermeiden.

Like this:
So wie hier:
```js
// the symbolic property is only known to our code
// die symbolische Eigenschaft ist nur unserem Code bekannt
let isRead = Symbol("isRead");
messages[0][isRead] = true;
```

Now third-party code probably won't see our extra property.
Jetzt wird Code von dritten unsere zusätzliche Eigenschaft wahrscheinlich nicht sehen.

Although symbols allow to lower the probability of problems, using `WeakSet` is better from the architectural point of view.
Obwohl Symbole die Wahrscheinlichkeit von Problemen verringern, ist die Verwendung von `WeakSet` aus architektonischer Sicht besser.
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
# Speicherung von "ungelesen"-Markierungen

There's an array of messages:
Gegeben sei ein Array von Nachrichten:

```js
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
{text: "Hallo", from: "John"},
{text: "Wie läuft's?", from: "John"},
{text: "Bis bald", 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.
Dein Code kann darauf zugreifen, aber die Nachrichten werden von anderem Code verwaltet. Neue Nachrichten werden hinzugefügt, alte regelmäßig entfernt, und du weißt nicht genau, in welchen Momenten das passiert.

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.
Welche Datenstruktur könntest du nun verwenden, um Informationen darüber zu speichern, ob die Nachricht "gelesen wurde"? Die Struktur muss gut geeignet sein, um die Frage "wurde es gelesen?" für das gegebene Nachrichtenobjekt zu beantworten.

P.S. When a message is removed from `messages`, it should disappear from your structure as well.
P.S. Wenn eine Nachricht aus `messages` entfernt wird, sollte sie auch aus deiner Struktur verschwinden.

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.
P.P.S. Wir sollten die Nachrichtenobjekte nicht modifizieren oder unsere Eigenschaften hinzufügen. Da sie von anderem Code verwaltet werden, könnte das zu schlechten Konsequenzen führen.
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@

To store a date, we can use `WeakMap`:
Um ein Datum zu speichern, können wir `WeakMap` verwenden:

```js
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
{text: "Hallo", from: "John"},
{text: "Wie läuft's?", from: "John"},
{text: "Bis bald", from: "Alice"}
];

let readMap = new WeakMap();

readMap.set(messages[0], new Date(2017, 1, 1));
// Date object we'll study later
// Date-Objekt, das wir später betrachten werden
```
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ importance: 5

---

# Store read dates
# Lesezeitpunkte speichern

There's an array of messages as in the [previous task](info:task/recipients-read). The situation is similar.
Es gibt ein Array von Nachrichten, wie in der [vorherigen Aufgabe](info:task/recipients-read). Die Situation ist ähnlich.

```js
let messages = [
{text: "Hello", from: "John"},
{text: "How goes?", from: "John"},
{text: "See you soon", from: "Alice"}
{text: "Hallo", from: "John"},
{text: "Wie läuft's?", from: "John"},
{text: "Bis bald", from: "Alice"}
];
```

The question now is: which data structure you'd suggest to store the information: "when the message was read?".
Die Frage lautet nun: Welche Datenstruktur würdest Du vorschlagen, um die Information zu speichern: "Wann wurde die Nachricht gelesen?".

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.
In der vorherigen Aufgabe mussten wir nur die Tatsache "ja/nein" speichern. Jetzt müssen wir das Datum speichern, und es sollte nur so lange im Speicher bleiben, bis die Nachricht vom Garbage Collector gelöscht wird.

P.S. Dates can be stored as objects of built-in `Date` class, that we'll cover later.
P.S. Daten können als Objekte der eingebauten `Date`-Klasse gespeichert werden, die wir später behandeln werden.
Loading