Suggest an editImprove this articleRefine the answer for “The Map collection in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`Map` is a built in collection of key, value pairs that remembers insertion order and accepts a key of any type, including objects, functions and `NaN`.** Unlike a plain object `{}`, where a key is always a string or a symbol, `Map` compares keys by reference, ships ready made methods `set`, `get`, `has`, `delete`, `clear`, exposes a `size` property instead of counting with `Object.keys().length`, and is iterable, so it works with `for...of`, `.forEach()`, `.keys()`, `.values()` and `.entries()`. `Map` wins wherever keys are added and removed often. ```javascript const map = new Map(); map.set('name', 'Alex'); console.log(map.get('name'), map.size); // Alex 1 ``` **Key point:** `Map` is an improved `{}`: any key type, guaranteed order, proper methods and a `size`.Shown above the full answer for quick recall.Answer (EN)Image**`Map` is a built in JavaScript object that stores key, value pairs and remembers the insertion order of those pairs.** It looks like a plain object `{}`, but it has extra abilities: a key may be any data type, it comes with convenient methods for adding, removing and iterating, and the order of elements is guaranteed. ## Theory ### TL;DR - `Map` is a collection of key, value pairs with a guaranteed insertion order. - A key can be anything: a string, a number, an object, a function, even `NaN`. - Object keys are compared by reference, not by their string representation. - Methods: `set`, `get`, `has`, `delete`, `clear`, plus the `size` property. - The collection is iterable: `for...of`, `.forEach()`, `.keys()`, `.values()`, `.entries()`. - Conversion works both ways: `new Map(Object.entries(obj))` and `Object.fromEntries(map)`. ### Quick example ```javascript const map = new Map(); map.set('name', 'Alex'); map.set('age', 25); console.log(map.get('name')); // Alex console.log(map.get('age')); // 25 console.log(map.size); // 2 ``` ### Core methods and properties | Method / property | What it does | Example | | --- | --- | --- | | `set(key, value)` | Adds an entry | `map.set('a', 1)` | | `get(key)` | Returns the value for a key | `map.get('a')` | | `has(key)` | Checks whether a key exists | `map.has('a') // true` | | `delete(key)` | Removes an entry | `map.delete('a')` | | `clear()` | Empties the whole collection | `map.clear()` | | `size` | Number of entries | `map.size // 2` | `set()` returns the `Map` itself, so calls can be chained: `map.set('a', 1).set('b', 2)`. ### Keys of any type ```javascript const map = new Map(); const objKey = { id: 1 }; const funcKey = () => {}; const numKey = 42; map.set(objKey, 'object'); map.set(funcKey, 'function'); map.set(numKey, 'number'); console.log(map.get(objKey)); // object console.log(map.get(funcKey)); // function console.log(map.get(42)); // number ``` Unlike a plain object `{}`, keys here are **compared by reference**, not by their stringified form. So `{ id: 1 }` and a fresh literal `{ id: 1 }` are two different keys. Even `NaN` works as a key, which is impossible in plain objects: ```javascript const map = new Map(); map.set(NaN, 'Not a Number'); console.log(map.get(NaN)); // 'Not a Number' ``` ### Iterating a Map `Map` is an **iterable collection**, so you can walk it in several ways. 1. `for...of`: ```javascript const map = new Map([ ['name', 'Alex'], ['age', 25], ]); for (const [key, value] of map) { console.log(`${key}: ${value}`); } // name: Alex // age: 25 ``` 2. The `forEach` method (mind the argument order: value first, key second): ```javascript map.forEach((value, key) => { console.log(key, value); }); ``` 3. Keys, values or entries separately: ```javascript console.log([...map.keys()]); // ['name', 'age'] console.log([...map.values()]); // ['Alex', 25] console.log([...map.entries()]); // [['name','Alex'], ['age',25]] ``` ### Map versus a plain object | Feature | `Object` | `Map` | | --- | --- | --- | | Key type | String or symbol only | Any type, including objects and functions | | Order of elements | Not guaranteed (before ES2015) | Guaranteed | | Number of entries | Counted manually (`Object.keys().length`) | `map.size` | | Removal | `delete obj.key` (slow) | `map.delete(key)` (fast) | | Iteration | `for...in` (picks up inherited properties) | Clean `for...of` | | Performance | Better for small data sets | Better for frequent inserts and deletes | ### Conversion and practical use From an object to a `Map`: ```javascript const obj = { a: 1, b: 2 }; const map = new Map(Object.entries(obj)); ``` From a `Map` to an object: ```javascript const obj2 = Object.fromEntries(map); ``` An occurrence counter, the classic case for a `Map`: ```javascript const arr = ['a', 'b', 'a', 'c', 'b', 'a']; const counter = new Map(); for (const item of arr) { counter.set(item, (counter.get(item) || 0) + 1); } console.log(counter); // Map(3) { 'a' => 3, 'b' => 2, 'c' => 1 } ``` Reach for `Map` when: - you need keys that are not only strings; - insertion order matters; - entries are added and removed often; - you are working with associative data structures. Short summary: | What | Description | | --- | --- | | **Type** | A key, value collection | | **Keys** | Any type, including objects | | **Order** | Preserved | | **Methods** | `.set()`, `.get()`, `.has()`, `.delete()`, `.clear()` | | **Size** | `map.size` | | **Iteration** | `for...of`, `.forEach()`, `.keys()`, `.values()`, `.entries()` | ### Common mistakes - **Treating a `Map` like an object.** `map['name']` creates a regular property on the `Map` object rather than an entry in the collection, and `map.get('name')` will return `undefined`. - **Expecting `map.length`.** A `Map` has no `length`, it has `size`, and that is a property, not a method. - **Using a fresh object literal as a lookup key.** `map.set({ id: 1 }, x)` and `map.get({ id: 1 })` are different references, so the result is `undefined`. - **Mixing up the `forEach` argument order.** The callback receives `(value, key, map)`, not `(key, value)`. - **Serialising a `Map` with `JSON.stringify`.** The result is `{}`; convert the collection into an object or an array first, for example with `Object.fromEntries(map)`. - **Keeping object keys in a `Map` and expecting garbage collection.** A `Map` holds strong references; for weak ones you need a `WeakMap`.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.