Зберігати мітки "непрочитане"
Є масив повідомлень:
let messages = [
{text: "Привіт", from: "Іван"},
{text: "Як справи?", from: "Іван"},
{text: "До зустрічі", from: "Аліса"}
];
Ваш код може отримати доступ до нього, але повідомлення керуються чужим кодом. Нові повідомлення додаються, старі видаляються регулярно цим кодом, і ви не знаєте точних моментів, коли це станеться.
Тепер, яку структуру даних ви могли б використати для зберігання інформації про те, чи було повідомлення прочитаним? Структура повинна добре підходити, щоб дати відповідь на питання “чи він прочитаний?” для об’єкта даного повідомлення.
P.S. Коли повідомлення видаляється з messages
, воно також повинне зникнути з вашої структури.
P.P.S. Ми не повинні змінювати об’єкти повідомлення, додаючи до них наші властивості. Оскільки вони керуються іншим кодом, це може призвести до поганих наслідків.
Збережемо прочитані повідомлення у WeakSet
:
let messages = [
{text: "Привіт", from: "Іван"},
{text: "Як справи?", from: "Іван"},
{text: "До зустрічі", from: "Аліса"}
];
let readMessages = new WeakSet();
// були прочитані два повідомлення
readMessages.add(messages[0]);
readMessages.add(messages[1]);
// readMessages має 2 елементи
// ...давайте знову прочитаємо перше повідомлення!
readMessages.add(messages[0]);
// readMessages все ще має 2 унікальних елементів
// відповідь: чи було messages[0] прочитано?
alert("Прочитано повідомлення 0: " + readMessages.has(messages[0])); // true
messages.shift();
// зараз readMessages має 1 елемент (з технічної точки зору пам’ять може бути очищена пізніше)
WeakSet
дозволяє зберігати набір повідомлень і легко перевірити наявність повідомлення в наборі.
Він автоматично очищає себе. Компроміс полягає в тому, що ми не можемо ітеруватися через нього, не можемо отримати “всі прочитані повідомлення” від нього безпосередньо. Але ми можемо це зробити, ітеруючись через всі повідомлення та відфільтрувавши тих, що знаходяться у наборі.
Інше рішення може полягати у додаванні властивості message.isRead=true
до повідомлення після його прочитання. Оскільки об’єкти повідомлень керуються іншим кодом, це, як правило, збентежує, але ми можемо використовувати символьну властивість, щоб уникнути конфліктів.
Ось так:
// символьна властивість відома лише в нашому коді
let isRead = Symbol("isRead");
messages[0][isRead] = true;
Тепер сторонній код, ймовірно, не побачить нашу додаткову властивість.
Незважаючи на те, що символи дозволяють знизити ймовірність проблем, використання WeakSet
краще з архітектурної точки зору.