Home >Web Front-end >JS Tutorial >What are WeakMaps in JS?

What are WeakMaps in JS?

Susan Sarandon
Susan SarandonOriginal
2024-12-27 08:45:10297browse

What are WeakMaps in JS?

A WeakMap in JavaScript is a collection of key-value pairs where the keys are required to be objects, and the references to these keys are "weak." This means that if there are no other references to a key object, it can be garbage-collected, even if it is still in the WeakMap.


Key Features

  1. Keys must be objects:

    • Primitive values (like numbers, strings, or booleans) cannot be used as keys.
    • Only objects and functions are allowed as keys.
  2. Weak references:

    • The key objects in a WeakMap are held weakly.
    • If no other references exist to a key, the key-value pair will be automatically removed from the WeakMap.
  3. Not iterable:

    • WeakMap does not have methods like forEach, and it cannot be looped through using constructs like for...of or Object.keys().
    • This is because the garbage collection process makes it impossible to reliably list all entries.
  4. Useful for private data:

    • WeakMap is often used to associate private data with objects without exposing it.

Syntax

const weakMap = new WeakMap();

Methods

Method Description
weakMap.set(key, value) Adds a new key-value pair or updates an existing key.
weakMap.get(key) Retrieves the value associated with the key.
weakMap.has(key) Checks if the key exists in the WeakMap.
weakMap.delete(key) Removes the key-value pair associated with the key.

Examples

Basic Usage

const weakMap = new WeakMap();

Garbage Collection

const weakMap = new WeakMap();

const obj1 = { name: "Alice" };
const obj2 = { name: "Bob" };

// Adding key-value pairs
weakMap.set(obj1, "Data for Alice");
weakMap.set(obj2, "Data for Bob");

// Accessing values
console.log(weakMap.get(obj1)); // Output: "Data for Alice"

// Checking existence
console.log(weakMap.has(obj2)); // Output: true

// Removing a key-value pair
weakMap.delete(obj2);
console.log(weakMap.has(obj2)); // Output: false

Use Cases

  1. Private Data Storage:
    • Associate private data with an object, ensuring it is not exposed or accessible elsewhere.
let obj = { key: "value" };
const weakMap = new WeakMap();
weakMap.set(obj, "Some data");

// Remove all references to `obj`
obj = null;

// The `WeakMap` entry for `obj` is automatically removed by garbage collection.
  1. DOM Node Metadata:
    • Store metadata related to DOM elements without preventing garbage collection.
const privateData = new WeakMap();

class User {
    constructor(name) {
        privateData.set(this, { name });
    }

    getName() {
        return privateData.get(this).name;
    }
}

const user = new User("Alice");
console.log(user.getName()); // Output: "Alice"

Advantages

  • Memory Efficiency: Automatic removal of unreferenced keys helps manage memory effectively.
  • Encapsulation: Provides a way to store data privately and securely.
  • No Memory Leaks: Prevents accidental memory leaks by allowing garbage collection of keys.

Limitations

  1. Non-iterable:
    • Cannot list all keys or values.
  2. Only Object Keys:
    • Does not support primitive keys.
  3. Limited Use Cases:
    • Not suitable for scenarios requiring enumeration or full access to stored data.

In summary, WeakMap is a specialized collection designed for scenarios where weak references and private associations are required.

Difference between Map and WeakMap

The primary difference between Map and WeakMap in JavaScript lies in their handling of keys, garbage collection, and functionality. Here’s a detailed comparison:


Key Differences

Feature
Feature Map WeakMap
Key Types Keys can be any type: objects, primitives. Keys must be objects.
Garbage Collection Does not rely on garbage collection; keys persist. Keys are held weakly and can be garbage-collected.
Iteration Iterable (can use for...of, forEach, etc.). Not iterable (cannot list keys or values).
Size Property Has a size property to get the number of entries. No size property available.
Use Case General-purpose key-value storage. Specialized for associating metadata or private data with objects.
Performance Slightly slower due to strong key references. Faster for memory-sensitive operations due to weak references.
Map
WeakMap
Key Types Keys can be any type: objects, primitives. Keys must be objects.
Garbage Collection Does not rely on garbage collection; keys persist. Keys are held weakly and can be garbage-collected.
Iteration Iterable (can use for...of, forEach, etc.). Not iterable (cannot list keys or values).
Size Property Has a size property to get the number of entries. No size property available.
Use Case General-purpose key-value storage. Specialized for associating metadata or private data with objects.
Performance Slightly slower due to strong key references. Faster for memory-sensitive operations due to weak references.

Feature Comparison

1. Key Types

  • Map: Accepts both objects and primitive types (like strings, numbers, booleans) as keys.
  • WeakMap: Only accepts objects as keys. Primitives are not allowed.
const weakMap = new WeakMap();

2. Garbage Collection

  • Map: Retains a strong reference to the key, preventing it from being garbage-collected as long as it exists in the map.
  • WeakMap: Holds a weak reference to the key, allowing it to be garbage-collected if there are no other references.
const weakMap = new WeakMap();

const obj1 = { name: "Alice" };
const obj2 = { name: "Bob" };

// Adding key-value pairs
weakMap.set(obj1, "Data for Alice");
weakMap.set(obj2, "Data for Bob");

// Accessing values
console.log(weakMap.get(obj1)); // Output: "Data for Alice"

// Checking existence
console.log(weakMap.has(obj2)); // Output: true

// Removing a key-value pair
weakMap.delete(obj2);
console.log(weakMap.has(obj2)); // Output: false

3. Iteration

  • Map: Iterable. You can use for...of, .keys(), .values(), .entries(), or .forEach() to iterate over its contents.
  • WeakMap: Not iterable. There are no methods to retrieve all keys, values, or entries.
let obj = { key: "value" };
const weakMap = new WeakMap();
weakMap.set(obj, "Some data");

// Remove all references to `obj`
obj = null;

// The `WeakMap` entry for `obj` is automatically removed by garbage collection.

4. Size Property

  • Map: Provides a size property that returns the number of entries.
  • WeakMap: Does not have a size property since it is not iterable and entries are weakly referenced.
const privateData = new WeakMap();

class User {
    constructor(name) {
        privateData.set(this, { name });
    }

    getName() {
        return privateData.get(this).name;
    }
}

const user = new User("Alice");
console.log(user.getName()); // Output: "Alice"

Use Cases

When to Use Map

  • General-purpose key-value storage.
  • Scenarios requiring enumeration or iteration of keys and values.
  • Keys may be primitives or objects.

Example:

const metadata = new WeakMap();

function trackElement(element) {
    metadata.set(element, { clicks: 0 });
}

function incrementClicks(element) {
    const data = metadata.get(element);
    if (data) {
        data.clicks++;
    }
}

const button = document.createElement("button");
trackElement(button);
incrementClicks(button);
console.log(metadata.get(button)); // Output: { clicks: 1 }

When to Use WeakMap

  • When you need to associate metadata or private data with objects without preventing garbage collection.
  • Ideal for cases where the lifetime of the key should dictate the lifetime of the associated value.

Example:

const map = new Map();
map.set(1, "value"); // Allowed
map.set("key", "value"); // Allowed
map.set({}, "value"); // Allowed

const weakMap = new WeakMap();
weakMap.set({}, "value"); // Allowed
weakMap.set(1, "value"); // TypeError: Invalid value used as weak map key

Summary

Feature
Feature Map WeakMap
Flexibility General-purpose, flexible. Specialized, limited use case.
Performance Persistent key references. Memory-efficient with weak references.
Suitability Iteration and long-term storage. Private data and ephemeral relationships.
Map
WeakMap
Flexibility General-purpose, flexible. Specialized, limited use case.
Performance Persistent key references. Memory-efficient with weak references.
Suitability Iteration and long-term storage. Private data and ephemeral relationships.

The above is the detailed content of What are WeakMaps in JS?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn