Jak dodać flagę 🚩do obiektu nie modyfikując go?

W programowaniu często mamy do czynienia z obiektami, które pobieramy z baz danych lub zewnętrznych źródeł poprzez interfejsy API. W niektórych przypadkach może zaistnieć potrzeba dodania do tych obiektów pewnych flag lub metadanych, które pomogą nam w dalszym przetwarzaniu i analizie danych. Warto jednak pamiętać, że modyfikowanie oryginalnych obiektów może prowadzić do niepożądanych efektów i utrudnić debugowanie kodu. Dlatego też warto zastanowić się nad wykorzystaniem struktur takich jak Map i WeakMap w celu przechowywania tych dodatkowych informacji.

Problem modyfikacji obiektów

Rozważmy przykład. Mamy obiekt reprezentujący osobę, którą pobraliśmy z bazy danych:

const person = { 
firstName: "John", 
lastName: "Ragnar", 
age: 31, 
city: "Łódź"

};

Naszym celem jest oznaczenie tej osoby jako "online" bez modyfikacji samego obiektu. Często możemy zastosować prostą metodę, jak dodanie flagi:

person.isOnline = true;

Jednakże, takie podejście modyfikuje obiekt, co w niektórych sytuacjach może prowadzić do niepożądanych efektów.

Masz dosyć czytania? Obejrzyj ten filmik, w którym Wojtek wytłumaczy Ci to wszystko szybko i prosto.

Wyświetl ten post na Instagramie

Post udostępniony przez Ragnarson (@ragnarsoncom)

Map i WeakMap

Utworzenie Mapy:

const myMap = new Map();

Mapa jest strukturą danych dostępną w języku JavaScript, która pozwala na przechowywanie pary klucz-wartość, gdzie klucze mogą być dowolnymi typami danych. W odróżnieniu od zwykłych obiektów, w mapach nie występuje problem z niespodziewanym nadpisaniem istniejących właściwości. Klucze w mapie są unikalne, co eliminuje ryzyko przypadkowej modyfikacji lub nadpisania wartości.

Utworzenie WeakMapy:

const myWeakMap = new WeakMap();

WeakMap to specjalna odmiana mapy, która ma pewne ograniczenia, ale również cenne zastosowanie w pewnych sytuacjach. Główną różnicą między WeakMapą a zwykłą Mapą jest to, że klucze w WeakMapie muszą być obiektami, a nie dowolnymi typami danych. Co więcej, klucze w WeakMapie nie są odporne na usuwanie przez mechanizm Garbage Collection (GC) w JavaScript. Jeśli jedyny odwołujący się do klucza obiekt zostanie usunięty, klucz i związane z nim dane również zostaną usunięte, co pomaga uniknąć wycieków pamięci.

Wykorzystanie WeakMap w celu dodawania flag

Zamiast jednak modyfikować oryginalny obiekt, możemy wykorzystać WeakMapę do przechowywania dodatkowych informacji.

Przypisanie Flagi:

const personData = new WeakMap(); 
personData.set(person, { isOnline: true });

Dzięki takiemu podejściu, nie modyfikujemy bezpośrednio obiektu person, co eliminuje ryzyko niezamierzonej zmiany innych właściwości. Jednocześnie mamy dostęp do dodanej flagi poprzez odwołanie się do WeakMapy personData.

const flagData = personData.get(person);
if (flagData && flagData.isOnline) {
  console.log(`${person.firstName} ${person.lastName} is online.`);
} else {
  console.log(`${person.firstName} ${person.lastName} is offline.`);
}

Podsumowanie

Unikanie bezpośredniej modyfikacji obiektów może pomóc w utrzymaniu czytelności i poprawności kodu. Wykorzystanie Map i WeakMap w celu przechowywania dodatkowych informacji, takich jak flagi czy metadane, pozwala na uniknięcie niepożądanych efektów ubocznych. Mapy pozwalają na przechowywanie różnych typów danych jako klucze i wartości. Natomiast WeakMapy, choć mają pewne ograniczenia, są przydatne w scenariuszach, gdzie chcemy uniknąć wycieków pamięci i nie zamierzamy dłużej używać kluczy. Pamiętajmy, że wybór odpowiedniej struktury zależy od kontekstu i wymagań naszego projektu.