`Map`-objekt
Denne artikel forklarer Map-objektet.
Vi forklarer trin for trin, fra grundlæggende operationer til praktiske eksempler, der er nyttige i virkelige scenarier.
YouTube Video
Map-objekt
Map er en samling, der gemmer nøgle-værdi-par. Det ligner et objekt, men adskiller sig ved, at enhver type, såsom objekter, funktioner eller primitive værdier, kan bruges som nøgler, og indsættelsesrækkefølgen bevares.
Grundlæggende om Map
Lad os først se på, hvordan man opretter en Map og udfører grundlæggende operationer.
Følgende kode er et minimalt eksempel, der opretter et tomt map, tilføjer nøgler og henter værdier.
1// Create an empty Map and add key-value pairs
2const m = new Map();
3m.set('a', 1);
4m.set('b', 2);
5
6console.log(m.get('a')); // 1
7console.log(m.size); // 2
- I denne kode kan du tilføje elementer med
set, hente værdier medget, og kontrollere antallet af elementer medsize. Mapbevarer indsættelsesrækkefølgen, hvilket gør den velegnet til rækkefølgeafhængig behandling.
Adfærd for set, get, has og delete
Her er eksempler på typiske læse-, skrive-, eksistenskontrol- og sletteoperationer.
Med den følgende kode kan du kontrollere returværdierne og effekterne af hver metode.
1// Demonstrate set, get, has, and delete
2const m2 = new Map();
3m2.set('x', 10);
4console.log(m2.has('x')); // true
5console.log(m2.get('y')); // undefined
6
7m2.delete('x');
8console.log(m2.has('x')); // false
9
10// set returns the map itself, allowing method chaining
11m2.set('a', 1).set('b', 2);
12console.log(m2); // Map { 'a' => 1, 'b' => 2 }
getreturnererundefined, hvis nøglen ikke findes.hastjekker for eksistensen af en nøgle, ogdeletefjerner en nøgle.- Da
setreturnerer selve mappen, er metodekædning mulig.
Enhver type kan bruges som en nøgle (herunder objekter som nøgler)
En af de største fordele ved Map er, at du kan bruge objekter direkte som nøgler.
Det følgende eksempel viser, hvordan man tilknytter værdier i en Map ved brug af objekter som nøgler.
1// Use objects as keys in a Map
2const keyObj = { id: 1 };
3const keyFunc = () => {};
4const objMap = new Map();
5
6// Another object with the same content but a different reference
7const anotherKeyObj = { id: 1 };
8
9objMap.set(keyObj, 'objectValue');
10objMap.set(keyFunc, 'functionValue');
11objMap.set(anotherKeyObj, 'anotherValue');
12
13console.log(objMap.get(keyObj)); // 'objectValue'
14console.log(objMap.get(keyFunc)); // 'functionValue'
15console.log(objMap.get(anotherKeyObj)); // 'anotherValue'
- Når man bruger objekter som nøgler, er det vigtigt, at de er den samme reference. Selv hvis deres indhold er det samme, bliver objekter med forskellige referencer behandlet som forskellige og er ikke den samme nøgle.
Iteration (gentagelse)
Map bevarer indsættelsesrækkefølgen, så iteration bruges ofte.
Nedenfor viser vi, hvordan man bruger for...of, forEach og metoderne keys(), values() og entries().
1// Iterating a Map with for...of and forEach
2const iterMap = new Map([['a', 1], ['b', 2], ['c', 3]]);
3
4// for...of over entries (default)
5for (const [key, value] of iterMap) {
6 console.log(key, value);
7}
8
9// forEach callback
10iterMap.forEach((value, key) => {
11 console.log(key, value);
12});
13
14// keys() and values()
15console.log([...iterMap.keys()]); // ['a','b','c']
16console.log([...iterMap.values()]); // [1,2,3]
entries()returnerer et array af[key, value]-par, som kan laves om til et array med spread-syntaksen. Bemærk, at callback'en forforEachmodtager argumenterne i rækkefølgenvalue, key.
Konvertering mellem Map og Object
Du kan konvertere et eksisterende objekt til en Map, eller konvertere en Map til et simpelt objekt eller array.
1// Convert between Map and Object / Array
2const obj = { a: 1, b: 2 };
3const mapFromObj = new Map(Object.entries(obj)); // Object -> Map
4console.log(mapFromObj.get('a')); // 1
5
6const objFromMap = Object.fromEntries(mapFromObj); // Map -> Object
7console.log(objFromMap); // { a: 1, b: 2 }
8
9const arrayFromMap = [...mapFromObj]; // Map -> Array of [key, value]
10console.log(arrayFromMap); // [['a',1], ['b',2]]
- Ved at bruge
Object.entriesogObject.fromEntrieser konvertering let. Da objekt-nøgler er begrænset til strenge eller symboler, går ikke-strengede nøgler tabt, når man konverterer tilbage til et objekt.
Praktisk mønster: Tælling af hyppighed (Count Map)
Når du tæller hyppigheden af elementer i et array, gør brugen af et Map processen enklere.
Den følgende kode er et eksempel på at bruge en map til at tælle hyppigheden af strenge i et array og sortere dem.
1// Count frequencies with Map
2const arr = ['apple','banana','apple','orange','banana','apple'];
3const freq = new Map();
4
5for (const item of arr) {
6 freq.set(item, (freq.get(item) || 0) + 1);
7}
8
9console.log([...freq.entries()]); // [['apple',3], ['banana',2], ['orange',1]]
- Ved at bruge en
Mapkan du nemt kontrollere eksistens og opdatere værdier. Dette kan også gøres med objekter, menMapkan være mere intuitiv, når man arbejder med vilkårlige nøgler.
Bemærkninger om Map og JSON.stringify (serialisering)
JSON.stringify kan ikke serialisere en Map direkte. Hvis du skal gemme en Map, skal du først konvertere den.
Følgende eksempel viser, hvordan man konverterer en Map til et array, før den omdannes til JSON, og hvordan man gendanner den igen.
1// Serialize and deserialize a Map
2const m3 = new Map([['x', 1], ['y', 2]]);
3const json = JSON.stringify([...m3]); // convert to array first
4console.log(json); // '[["x",1],["y",2]]'
5
6const restored = new Map(JSON.parse(json));
7console.log(restored.get('x')); // 1
- Maps, der skal gemmes eller overføres, bør konverteres til arrays, før de serialiseres. Når du gendanner, skal du bruge
JSON.parsetil at omdanne det til et array og derefter lave det tilbage til en Map.
Introduktion til WeakMap og hvordan man bruger det
WeakMap adskiller sig ved, at dets nøgler er svagt refererede (underlagt garbage collection).
Den er nyttig til at holde cache eller metadata, hvor objekter bruges som nøgler, og de frigøres automatisk, når nøgle-objektet bliver samlet op (garbage collected).
1// WeakMap for metadata tied to object lifecycle
2const wm = new WeakMap();
3let obj = {};
4wm.set(obj, { meta: 'info' });
5console.log(wm.get(obj)); // { meta: 'info' }
6
7obj = null; // now the object can be GC'd and its entry removed from WeakMap
WeakMapkan ikke gennemløbes eller få kontrolleret sin størrelse, men er nyttig for at undgå memory leaks.
Sammendrag
Map er en praktisk samling, der, i modsætning til objekter, tillader enhver type som nøgle og bevarer indsættelsesrækkefølgen. Ved at forstå alt fra grundlæggende operationer til avanceret brug kan du håndtere data mere fleksibelt og intuitivt. Ved at bruge Object og Map korrekt i forhold til brugstilfældet kan du forbedre kodens klarhed og læsbarhed betydeligt.
Du kan følge med i ovenstående artikel ved hjælp af Visual Studio Code på vores YouTube-kanal. Husk også at tjekke YouTube-kanalen.