Jsref Map
## Introduction
In modern JavaScript development (ES6 and later), the `Map` object is a powerful collection of key-value pairs. Unlike standard JavaScript objects (`Object`), a `Map` remembers the original insertion order of the keys and allows keys of **any type**βincluding functions, objects, and primitive types.
This comprehensive reference guide covers the syntax, properties, methods, and practical use cases of the JavaScript `Map` object (often referred to as `Jsref Map` in developer references).
---
## Syntax and Initialization
To create a new `Map`, use the `Map` constructor. You can optionally pass an iterable object (such as an Array of arrays) to initialize the map with key-value pairs.
### Syntax
```javascript
// Create an empty Map
const myMap = new Map();
// Create a Map initialized with key-value pairs
const initializedMap = new Map([
['key1', 'value1'],
['key2', 'value2']
]);
```
### Key Differences: `Map` vs. `Object`
| Feature | `Map` | `Object` |
| :--- | :--- | :--- |
| **Key Types** | Any value (Objects, Functions, Primitives) | String or Symbol only |
| **Key Order** | Preserves insertion order | Not guaranteed (historically unordered) |
| **Size Retrieval** | Easily retrieved via the `.size` property | Must be calculated manually (e.g., `Object.keys(obj).length`) |
| **Performance** | Optimized for frequent additions and removals | Not optimized for intensive key-value additions |
| **Iterability** | Directly iterable | Requires helper methods (e.g., `Object.entries()`) |
---
## Properties and Methods
The `Map` prototype provides a rich set of built-in properties and methods to manage your collections.
### Instance Properties
* **`size`**: Returns the number of key-value pairs in the `Map` object.
### Instance Methods
#### 1. Adding & Modifying Elements
* **`set(key, value)`**: Adds or updates a key-value pair. Returns the `Map` object (allowing chaining).
#### 2. Retrieving Elements
* **`get(key)`**: Returns the value associated with the specified key. Returns `undefined` if the key does not exist.
* **`has(key)`**: Returns a boolean indicating whether an element with the specified key exists.
#### 3. Removing Elements
* **`delete(key)`**: Removes the specified element. Returns `true` if the element existed and was removed, `false` otherwise.
* **`clear()`**: Removes all key-value pairs from the `Map` object.
#### 4. Iteration Methods
* **`keys()`**: Returns a new Iterator object containing the keys for each element in insertion order.
* **`values()`**: Returns a new Iterator object containing the values for each element in insertion order.
* **`entries()`**: Returns a new Iterator object containing `[key, value]` pairs.
* **`forEach(callbackFn[, thisArg])`**: Executes a provided function once per key-value pair.
---
## Code Examples
### 1. Basic Operations (CRUD)
Here is how to perform basic Create, Read, Update, and Delete operations on a `Map`.
```javascript
// 1. Initialize a Map
const userRoles = new Map();
// 2. Set values (Create/Update)
userRoles.set('alice', 'Admin');
userRoles.set('bob', 'Editor');
userRoles.set('charlie', 'Subscriber');
// Chaining .set()
userRoles.set('david', 'Guest').set('emma', 'Editor');
// 3. Get values (Read)
console.log(userRoles.get('alice')); // Output: "Admin"
console.log(userRoles.get('frank')); // Output: undefined
// 4. Check existence
console.log(userRoles.has('bob')); // Output: true
console.log(userRoles.has('frank')); // Output: false
// 5. Get size
console.log(userRoles.size); // Output: 5
// 6. Delete an entry
userRoles.delete('charlie');
console.log(userRoles.has('charlie')); // Output: false
console.log(userRoles.size); // Output: 4
// 7. Clear all entries
userRoles.clear();
console.log(userRoles.size); // Output: 0
```
### 2. Using Complex Key Types
Unlike standard objects, `Map` allows you to use objects, arrays, and functions as keys.
```javascript
const registry = new Map();
// Using objects as keys
const user1 = { name: 'John' };
const user2 = { name: 'Jane' };
registry.set(user1, 'Metadata for John');
registry.set(user2, 'Metadata for Jane');
console.log(registry.get(user1)); // Output: "Metadata for John"
// Using a function as a key
const myFunction = () => {};
registry.set(myFunction, 'Function metadata');
console.log(registry.get(myFunction)); // Output: "Function metadata"
```
### 3. Iterating Over a Map
There are multiple ways to loop through the elements of a `Map`.
```javascript
const fruitInventory = new Map([
['apples', 500],
['bananas', 350],
['oranges', 200]
]);
// Loop using for...of (destructuring key and value)
for (const [fruit, quantity] of fruitInventory) {
console.log(`We have ${quantity} bags of ${fruit}.`);
}
// Loop using keys()
for (const fruit of fruitInventory.keys()) {
console.log(`Fruit: ${fruit}`);
}
// Loop using values()
for (const quantity of fruitInventory.values()) {
console.log(`Quantity: ${quantity}`);
}
// Loop using forEach()
fruitInventory.forEach((value, key) => {
console.log(`${key} has a stock of ${value}`);
});
```
### 4. Converting Between Map and Array
You can easily convert a `Map` to a 2D Array and vice versa using the spread operator (`...`) or `Array.from()`.
```javascript
const map = new Map([
['a', 1],
['b', 2]
]);
// Convert Map to 2D Array
const arrayFromMap = [...map];
// Or: const arrayFromMap = Array.from(map);
console.log(arrayFromMap);
// Output: [ ['a', 1], ['b', 2] ]
// Convert Map keys to Array
const keysArray = [...map.keys()];
console.log(keysArray); // Output: ['a', 'b']
// Convert Map values to Array
const valuesArray = [...map.values()];
console.log(valuesArray); // Output: [1, 2]
```
---
## Key Considerations & Best Practices
* **Key Equality (`SameValueZero` algorithm)**: `Map` uses the `SameValueZero` algorithm to determine key equality. This means `NaN` is considered equal to `NaN` (even though `NaN !== NaN` in standard JS), and `-0` is considered equal to `+0`.
* **Object Reference Equality**: When using objects as keys, the lookup is based on the object's **reference**, not its structural value.
```javascript
const map = new Map();
map.set({}, 'anonymous');
console.log(map.get({})); // Output: undefined (since the two {} are different object references)
```
* **Memory Leaks**: If you use objects as keys in a standard `Map`, those objects cannot be garbage collected as long as the `Map` exists. If you need keys to be weakly referenced (allowing garbage collection when no other references exist), consider using **`WeakMap`**.
* **Avoid Direct Property Assignment**: Do not populate a map using `map.key = value` or `map['key'] = value`. While this technically works because a `Map` is a JavaScript object, it bypasses the internal `Map` data structure and does not use the `.set()` method. This means you cannot use `.get()`, `.has()`, or `.size` on those properties.
YouTip