Objektet `Map`
Den här artikeln förklarar objektet Map.
Vi förklarar steg för steg, från grundläggande operationer till praktiska exempel som är användbara i verkliga situationer.
YouTube Video
Objektet Map
Map är en samling som lagrar nyckel-värde-par. Det liknar ett objekt, men skiljer sig genom att vilken typ som helst, såsom objekt, funktioner eller primitiva värden, kan användas som nycklar och att insättningsordningen bevaras.
Grunderna i Map
Låt oss först se hur man skapar en Map och utför grundläggande operationer.
Följande kod är ett minimalt exempel som skapar en tom map, lägger till nycklar och hämtar värden.
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 den här koden kan du lägga till element med
set, hämta värden medgetoch kontrollera antalet element medsize. Mapbehåller insättningsordningen, vilket gör den lämplig för ordningsberoende bearbetning.
Beteendet för set, get, has och delete
Här är exempel på typiska läs-, skriv-, existenskontroll- och raderingsoperationer.
Med följande kod kan du kontrollera returvärdena och effekterna av varje metod.
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 }
getreturnerarundefinedom nyckeln inte finns.haskontrollerar om en nyckel finns, ochdeletetar bort en nyckel.- Eftersom
setreturnerar själva mappen är metodkedjning möjlig.
Vilken typ som helst kan användas som nyckel (använda objekt som nycklar)
En av de största fördelarna med Map är att du kan använda objekt direkt som nycklar.
Följande exempel visar hur man kopplar värden i en Map med objekt som nycklar.
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 använder objekt som nycklar är det viktigt att de är samma referens. Även om deras innehåll är detsamma behandlas objekt med olika referenser som olika och är inte samma nyckel.
Iteration (loopning)
Map behåller insättningsordningen så iteration används ofta.
Nedan visar vi hur man använder for...of, forEach samt metoderna keys(), values() och 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()returnerar en array av[key, value]-par, som kan förvandlas till en array med spridningssyntaxen. Observera att callbacken förforEachtar emot argumenten i ordningenvalue, key.
Konvertera mellan Map och Object
Du kan konvertera ett befintligt objekt till en Map eller konvertera en Map till ett vanligt objekt eller en 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]]
- Att använda
Object.entriesochObject.fromEntriesgör konvertering enkelt. Eftersom objektets nycklar är begränsade till strängar eller symboler så förloras icke-sträng-nycklar vid konvertering tillbaka till ett objekt.
Praktiskt mönster: Frekvensräkning (Count Map)
När man räknar frekvensen av element i en array blir processen enklare med en Map.
Följande kod är ett exempel på hur man använder en Map för att räkna antalet förekomster av strängar i en array och sortera 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]]
- Att använda en
Maptillåter enkla existenskontroller och uppdateringar. Detta kan göras med objekt också, menMapkan vara mer intuitiv när man arbetar med godtyckliga nycklar.
Observera om Map och JSON.stringify (serialisering)
JSON.stringify kan inte serialisera en Map direkt. Om du behöver spara en Map måste du först konvertera den.
Följande exempel visar hur man konverterar en Map till en array innan den görs om till JSON och hur man återställer den.
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
- Mappar som behöver sparas eller skickas bör konverteras till arrayer innan serialisering. När du återställer, använd
JSON.parseför att konvertera till en array och skapa sedan tillbaka till en Map.
Introduktion till WeakMap och hur man använder den
WeakMap skiljer sig genom att dess nycklar är svagt refererade (föremål för garbage collection).
Den är användbar för att lagra cache eller metadata med objekt som nycklar och frigör dem automatiskt när nyckelobjektet samlas in (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 inte enumreras eller få sin storlek kontrollerad, men är användbar för att förhindra minnesläckor.
Sammanfattning
Map är en praktisk samling som, till skillnad från objekt, tillåter vilken typ som helst som nyckel och bevarar insättningsordningen. Genom att förstå allt från grundläggande operationer till avancerad användning kan du hantera data mer flexibelt och intuitivt. Genom att använda Object och Map på rätt sätt för användningsområdet kan du avsevärt förbättra kodens klarhet och läsbarhet.
Du kan följa med i artikeln ovan med hjälp av Visual Studio Code på vår YouTube-kanal. Vänligen kolla även in YouTube-kanalen.