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 in developer references as `Jsref Map`).
---
## Why Use Map Over Object?
While standard JavaScript objects have historically been used to store key-value pairs, `Map` offers several distinct advantages:
| Feature | `Map` | `Object` |
| :--- | :--- | :--- |
| **Key Types** | Any value (Objects, Functions, Primitives). | Must be String or Symbol. |
| **Key Order** | Preserves insertion order. | Not reliably ordered (historically). |
| **Size Retrieval** | Easily retrieved via the `.size` property. | Must be determined manually (e.g., `Object.keys(obj).length`). |
| **Performance** | Optimized for frequent additions and removals of key-value pairs. | Not specifically optimized for frequent additions/removals. |
| **Default Keys** | Contains no keys by default (only what you explicitly add). | Inherits prototype properties (e.g., `toString`) unless created with `Object.create(null)`. |
---
## Syntax and Initialization
### Creating an Empty Map
```javascript
const myMap = new Map();
```
### Creating a Map with Initial Values
You can initialize a `Map` by passing an iterable object (such as an Array) containing two-element arrays `[key, value]`.
```javascript
const userRoles = new Map([
['admin', 'Access to all settings'],
['editor', 'Access to publish content'],
['viewer', 'Access to read-only content']
]);
```
---
## Instance Properties and Methods
### Properties
* **`Map.prototype.size`**: Returns the number of key-value pairs in the `Map` object.
### Basic Methods (CRUD Operations)
| Method | Description | Syntax |
| :--- | :--- | :--- |
| **`set(key, value)`** | Adds or updates an element with a specified key and value. Returns the `Map` object (chainable). | `map.set('id', 101);` |
| **`get(key)`** | Returns the value associated with the key, or `undefined` if the key doesn't exist. | `map.get('id');` |
| **`has(key)`** | Returns a boolean asserting whether a value has been associated with the key. | `map.has('id');` |
| **`delete(key)`** | Removes the specified element. Returns `true` if the element existed and was removed, else `false`. | `map.delete('id');` |
| **`clear()`** | Removes all key-value pairs from the `Map` object. | `map.clear();` |
### Iteration Methods
| Method | Description |
| :--- | :--- |
| **`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 an array of `[key, value]` for each element. |
| **`forEach(callbackFn)`** | Calls `callbackFn` once for each key-value pair present in the Map, in insertion order. |
---
## Code Examples
### 1. Basic Operations (CRUD)
This example demonstrates how to create a Map, add elements, check for existence, retrieve values, and delete entries.
```javascript
// Initialize Map
const productInventory = new Map();
// 1. Set values (Writing data)
productInventory.set('Laptop', 15);
productInventory.set('Smartphone', 42);
productInventory.set('Headphones', 100);
// 2. Get values (Reading data)
console.log(productInventory.get('Laptop')); // Output: 15
console.log(productInventory.get('Tablet')); // Output: undefined (key does not exist)
// 3. Check existence
console.log(productInventory.has('Smartphone')); // Output: true
console.log(productInventory.has('Tablet')); // Output: false
// 4. Get size
console.log(productInventory.size); // Output: 3
// 5. Delete an item
productInventory.delete('Headphones');
console.log(productInventory.has('Headphones')); // Output: false
console.log(productInventory.size); // Output: 2
// 6. Clear all items
productInventory.clear();
console.log(productInventory.size); // Output: 0
```
### 2. Using Non-String Keys
One of the most powerful features of `Map` is the ability to use objects, functions, or any primitive as keys.
```javascript
const userSession = new Map();
// Using Objects as keys
const userAlice = { name: 'Alice', id: 1001 };
const userBob = { name: 'Bob', id: 1002 };
userSession.set(userAlice, { lastLogin: '10:30 AM', active: true });
userSession.set(userBob, { lastLogin: '11:15 AM', active: false });
// Accessing data using the object reference
console.log(userSession.get(userAlice));
// Output: { lastLogin: '10:30 AM', active: true }
// Using a Function as a key
const logAction = function() { return 'logging'; };
userSession.set(logAction, 'System Logger Function');
console.log(userSession.get(logAction)); // Output: 'System Logger Function'
```
### 3. Iterating Over a Map
There are multiple ways to loop through a `Map` object.
```javascript
const fruitPrices = new Map([
['Apple', 1.2],
['Banana', 0.5],
['Orange', 0.8]
]);
// Loop using for...of (destructuring entries)
for (const [fruit, price] of fruitPrices) {
console.log(`The price of ${fruit} is $${price}`);
}
// Loop using forEach
fruitPrices.forEach((price, fruit) => {
console.log(`Fruit: ${fruit}, Price: $${price}`);
});
// Iterating over keys only
for (const fruit of fruitPrices.keys()) {
console.log(`Available fruit: ${fruit}`);
}
// Iterating over values only
for (const price of fruitPrices.values()) {
console.log(`Price point: $${price}`);
}
```
### 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 originalMap = new Map([
['key1', 'value1'],
['key2', 'value2']
]);
// Convert Map to a 2D Array
const mapAsArray = [...originalMap];
console.log(mapAsArray);
// Output: [ ['key1', 'value1'], ['key2', 'value2'] ]
// Convert Map keys to an Array
const keysArray = Array.from(originalMap.keys());
console.log(keysArray); // Output: ['key1', 'key2']
// Convert Map values to an Array
const valuesArray = Array.from(originalMap.values());
console.log(valuesArray); // Output: ['value1', 'value2']
```
---
## Important Considerations & Best Practices
### 1. Key Equality (SameValueZero Algorithm)
`Map` uses the **SameValueZero** algorithm to determine key equality.
* `NaN` is considered equal to `NaN` (even though `NaN !== NaN` in standard JavaScript). Therefore, you can use `NaN` as a single key.
* `-0` and `+0` are considered equal.
* Objects and Arrays are compared by **reference**, not by value.
```javascript
const map = new Map();
// Object reference example
map.set({}, 'Value A');
console.log(map.get({})); // Output: undefined (Because the two {} are different object references in memory)
const myObj = {};
map.set(myObj, 'Value B');
console.log(map.get(myObj)); // Output: 'Value B' (Same reference)
```
### 2. Avoid Using Standard Object Syntax on Maps
While you *can* write `map['key'] = value` because a Map is technically a JavaScript object, doing so bypasses the Map's internal storage mechanism. It does not register the key-value pair in the Map's metadata.
```javascript
const badMap = new Map();
badMap['wrongWay'] = 'This is bad'; // Do NOT do this!
console.log(badMap.has('wrongWay')); // Output: false
console.log(badMap.get('wrongWay')); // Output: undefined
console.log(badMap.size); // Output: 0
```
**Rule of thumb:** Always use `.set()`, `.get()`, and `.has()` when working with Maps.
### 3. Memory Leaks and Garbage Collection
If you use objects as keys in a standard `Map`, those objects cannot be garbage-collected as long as the `Map` exists, even if there are no other references to the object. If you need keys to be garbage-collected when they are no longer referenced elsewhere, consider using **`WeakMap`**.
YouTip