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.
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.