Odejdźmy teraz od poszczególnych struktur danych i porozmawiajmy o iteracjach nad nimi.
W poprzednim rozdziale widzieliśmy metody map.keys()
, map.values()
, map.entries()
.
Metody te są generyczne, istnieje powszechna zgoda na używanie ich dla struktur danych. Jeśli kiedykolwiek stworzymy własną strukturę danych, powinniśmy je również zaimplementować.
Są one obsługiwane dla:
Map
Set
Array
Plain objects również obsługują podobne metody, ale składnia jest nieco inna.
Object.keys, values, entries
Dla obiektów typu plain dostępne są następujące metody:
- Object.keys(obj) – zwraca tablicę kluczy.
- Object.values(obj) – zwraca tablicę wartości.
- Object.entries(obj) – zwraca tablicę
par.
Proszę zwrócić uwagę na rozróżnienia (w porównaniu do mapy na przykład):
Map | Object | |
---|---|---|
Składnia wywołania | map.keys() |
Object.keys(obj) , ale nie obj.keys() |
Returns | iterable | „real” Array |
Pierwszą różnicą jest to, że musimy wywołać Object.keys(obj)
, a nie obj.keys()
.
Dlaczego? Głównym powodem jest elastyczność. Pamiętajmy, że obiekty są podstawą wszystkich złożonych struktur w JavaScript. Możemy więc mieć własny obiekt, taki jak data
, który implementuje swoją własną metodę data.values()
. I nadal możemy na nim wywołać Object.values(data)
.
Drugą różnicą jest to, że metody Object.*
zwracają „prawdziwe” obiekty tablicowe, a nie tylko iterowalne. Jest to głównie z powodów historycznych.
Na przykład:
let user = { name: "John", age: 30};
Object.keys(user) =
Object.values(user) =
Object.entries(user) = , ]
Oto przykład użycia Object.values
do zapętlenia wartości właściwości:
let user = { name: "John", age: 30};// loop over valuesfor (let value of Object.values(user)) { alert(value); // John, then 30}
Tak jak pętla for..in
, metody te ignorują właściwości, które używają Symbol(...)
jako kluczy.
Zwykle jest to wygodne. Ale jeśli chcemy mieć również klucze symboliczne, to istnieje osobna metoda Object.getOwnPropertySymbols, która zwraca tablicę tylko kluczy symbolicznych. Istnieje również metoda Reflect.ownKeys(obj), która zwraca wszystkie klucze.
Transformowanie obiektów
Obiektom brakuje wielu metod, które istnieją dla tablic, np. map
, filter
i innych.
Jeśli chcielibyśmy je zastosować, to możemy użyć Object.entries
, a następnie Object.fromEntries
:
- Użyj
Object.entries(obj)
, aby uzyskać tablicę par klucz/wartość zobj
. - Użyj metod tablicowych na tej tablicy, np.
map
. - Użyj
Object.fromEntries(array)
na wynikowej tablicy, aby przekształcić ją z powrotem w obiekt.
Na przykład, mamy obiekt z cenami i chcielibyśmy je podwoić:
let prices = { banana: 1, orange: 2, meat: 4,};let doublePrices = Object.fromEntries( // convert to array, map, and then fromEntries gives back the object Object.entries(prices).map(() => ));alert(doublePrices.meat); // 8
To może wyglądać trudno na pierwszy rzut oka, ale staje się łatwe do zrozumienia po użyciu go raz lub dwa razy. Możemy w ten sposób tworzyć potężne łańcuchy transformacji.